forked from len0rd/rockbox
[1/4] Remove SH support and all archos targets
This removes all code specific to SH targets Change-Id: I7980523785d2596e65c06430f4638eec74a06061
This commit is contained in:
parent
17f7cc92c2
commit
092c340a20
384 changed files with 648 additions and 43225 deletions
|
|
@ -39,9 +39,9 @@ profile.c
|
|||
#if !defined(RKW_FORMAT) && !defined(MI4_FORMAT) && defined(MODEL_NUMBER)
|
||||
common/rb-loader.c
|
||||
#endif
|
||||
#if !defined(BOOTLOADER) || defined(CPU_SH)
|
||||
#if !defined(BOOTLOADER)
|
||||
rolo.c
|
||||
#endif /* !defined(BOOTLOADER) || defined(CPU_SH) */
|
||||
#endif /* !defined(BOOTLOADER) */
|
||||
timer.c
|
||||
debug.c
|
||||
#endif /* PLATFORM_NATIVE */
|
||||
|
|
@ -361,9 +361,7 @@ eeprom_settings.c
|
|||
|
||||
/* RTC */
|
||||
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
||||
#if (CONFIG_RTC == RTC_M41ST84W)
|
||||
drivers/rtc/rtc_m41st84w.c
|
||||
#elif (CONFIG_RTC == RTC_PCF50606)
|
||||
#if (CONFIG_RTC == RTC_PCF50606)
|
||||
drivers/rtc/rtc_pcf50606.c
|
||||
#elif (CONFIG_RTC == RTC_PCF50605)
|
||||
drivers/rtc/rtc_pcf50605.c
|
||||
|
|
@ -406,10 +404,6 @@ tuner.c
|
|||
#if (CONFIG_TUNER & LV24020LP)
|
||||
drivers/tuner/lv24020lp.c
|
||||
#endif /* (CONFIG_TUNER & LV24020LP) */
|
||||
#if (CONFIG_TUNER & S1A0903X01)
|
||||
drivers/fmradio.c
|
||||
drivers/tuner/s1a0903x01.c
|
||||
#endif /* (CONFIG_TUNER & S1A0903X01) */
|
||||
#if (CONFIG_TUNER & TEA5760)
|
||||
drivers/tuner/tea5760uk.c
|
||||
#endif
|
||||
|
|
@ -480,8 +474,6 @@ drivers/audio/wm8731.c
|
|||
drivers/audio/as3514.c
|
||||
#elif defined(HAVE_TLV320)
|
||||
drivers/audio/tlv320.c
|
||||
#elif defined(HAVE_MAS35XX)
|
||||
drivers/audio/mas35xx.c
|
||||
#elif defined(HAVE_AK4537)
|
||||
drivers/audio/ak4537.c
|
||||
#elif defined(HAVE_UDA1341)
|
||||
|
|
@ -531,18 +523,7 @@ target/hosted/sdl/pcm-sdl.c
|
|||
#endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(BOOTLOADER) */
|
||||
|
||||
/* CPU Specific - By class then particular chip if applicable */
|
||||
#if defined(CPU_SH)
|
||||
|
||||
target/sh/adc-sh.c
|
||||
target/sh/bitswap.S
|
||||
target/sh/crt0.S
|
||||
target/sh/kernel-sh.c
|
||||
target/sh/system-sh.c
|
||||
target/sh/archos/descramble.S
|
||||
target/sh/archos/i2c-archos.c
|
||||
target/sh/debug-sh.c
|
||||
|
||||
#elif defined(CPU_COLDFIRE)
|
||||
#if defined(CPU_COLDFIRE)
|
||||
|
||||
target/coldfire/crt0.S
|
||||
target/coldfire/kernel-coldfire.c
|
||||
|
|
@ -786,16 +767,8 @@ drivers/i2c.c
|
|||
/* LCD driver */
|
||||
#if CONFIG_LCD == LCD_SSD1303
|
||||
target/arm/as3525/lcd-ssd1303.c
|
||||
#elif CONFIG_LCD == LCD_SSD1801
|
||||
target/sh/archos/player/lcd-as-player.S
|
||||
target/sh/archos/player/lcd-player.c
|
||||
#elif CONFIG_LCD == LCD_SSD1815
|
||||
# if CONFIG_CPU == SH7034
|
||||
target/sh/archos/lcd-archos-bitmap.c
|
||||
target/sh/archos/lcd-as-archos-bitmap.S
|
||||
# else
|
||||
target/arm/lcd-ssd1815.c
|
||||
# endif
|
||||
#elif CONFIG_LCD == LCD_HX8340B
|
||||
target/arm/rk27xx/lcd-hifiman.c
|
||||
#elif CONFIG_LCD == LCD_C200
|
||||
|
|
@ -907,19 +880,6 @@ target/arm/tcc77x/adc-tcc77x.c
|
|||
|
||||
#endif /* CONFIG_I2C */
|
||||
|
||||
#ifdef CPU_SH
|
||||
target/sh/archos/mascodec-archos.c
|
||||
target/sh/archos/audio-archos.c
|
||||
target/sh/archos/timer-archos.c
|
||||
# if CONFIG_STORAGE & STORAGE_ATA
|
||||
target/sh/archos/ata-archos.c
|
||||
target/sh/archos/ata-as-archos.S
|
||||
# endif
|
||||
# ifdef HAVE_SERIAL
|
||||
target/sh/archos/uart-archos.c
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CPU_TCC77X
|
||||
target/arm/usb-tcc.c
|
||||
target/arm/tcc77x/kernel-tcc77x.c
|
||||
|
|
@ -958,39 +918,6 @@ target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
|
|||
# endif
|
||||
#endif /* CONFIG_CPU == S3C2440 */
|
||||
|
||||
#ifdef ARCHOS_PLAYER
|
||||
target/sh/archos/player/button-player.c
|
||||
target/sh/archos/player/hwcompat-player.c
|
||||
target/sh/archos/player/power-player.c
|
||||
target/sh/archos/player/powermgmt-player.c
|
||||
target/sh/archos/player/usb-player.c
|
||||
#endif /* ARCHOS_PLAYER */
|
||||
|
||||
#ifdef ARCHOS_RECORDER
|
||||
target/sh/archos/recorder/button-recorder.c
|
||||
target/sh/archos/recorder/power-recorder.c
|
||||
target/sh/archos/recorder/powermgmt-recorder.c
|
||||
target/sh/archos/recorder/usb-recorder.c
|
||||
#endif /* ARCHOS_RECORDER */
|
||||
|
||||
#if defined(ARCHOS_FMRECORDER) || defined(ARCHOS_RECORDERV2)
|
||||
target/sh/archos/fm_v2/button-fm_v2.c
|
||||
target/sh/archos/fm_v2/power-fm_v2.c
|
||||
target/sh/archos/fm_v2/powermgmt-fm_v2.c
|
||||
target/sh/archos/fm_v2/usb-fm_v2.c
|
||||
#endif /* ARCHOS_FMRECORDER || ARCHOS_RECORDERV2 */
|
||||
|
||||
#if defined(ARCHOS_ONDIOFM) || defined(ARCHOS_ONDIOSP)
|
||||
target/sh/archos/ondio/button-ondio.c
|
||||
target/sh/archos/ondio/power-ondio.c
|
||||
target/sh/archos/ondio/powermgmt-ondio.c
|
||||
target/sh/archos/ondio/usb-ondio.c
|
||||
target/sh/archos/ondio/ata_mmc.c
|
||||
#if (CONFIG_TUNER & TEA5767)
|
||||
target/sh/archos/ondio/fmradio_i2c-ondio.c
|
||||
#endif
|
||||
#endif /* ARCHOS_ONDIOFM || ARCHOS_ONDIOFM */
|
||||
|
||||
#if defined(SANSA_E200) || defined(SANSA_C200)
|
||||
target/arm/sandisk/backlight-c200_e200.c
|
||||
target/arm/sandisk/power-c200_e200.c
|
||||
|
|
|
|||
|
|
@ -1,227 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004-2005 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _memcpy
|
||||
.global _mempcpy
|
||||
.global ___memcpy_fwd_entry
|
||||
.type _memcpy,@function
|
||||
.type _mempcpy,@function
|
||||
|
||||
/* Copies <length> bytes of data in memory from <source> to <dest>
|
||||
* This version is optimized for speed
|
||||
*
|
||||
* arguments:
|
||||
* r4 - destination address
|
||||
* r5 - source address
|
||||
* r6 - length
|
||||
*
|
||||
* return value:
|
||||
* r0 - destination address (like ANSI version)
|
||||
*
|
||||
* register usage:
|
||||
* r0 - data / scratch
|
||||
* r1 - 2nd data / scratch
|
||||
* r2 - scratch
|
||||
* r3 - first long bound / adjusted end address (only if >= 11 bytes)
|
||||
* r4 - current dest address
|
||||
* r5 - current source address
|
||||
* r6 - source end address
|
||||
* r7 - stored dest start address
|
||||
*
|
||||
* The instruction order is devised in a way to utilize the pipelining
|
||||
* of the SH1 to the max. The routine also tries to utilize fast page mode.
|
||||
*/
|
||||
_mempcpy:
|
||||
mov r4,r7 /* store dest + length for returning */
|
||||
bra ___memcpy_fwd_entry
|
||||
add r6,r7
|
||||
|
||||
_memcpy:
|
||||
mov r4,r7 /* store dest for returning */
|
||||
___memcpy_fwd_entry:
|
||||
add #-8,r4 /* offset for early increment (max. 2 longs) */
|
||||
mov #11,r0
|
||||
cmp/hs r0,r6 /* at least 11 bytes to copy? (ensures 2 aligned longs) */
|
||||
add r5,r6 /* r6 = source_end */
|
||||
bf .start_b2 /* no: jump directly to byte loop */
|
||||
|
||||
mov #3,r0
|
||||
neg r5,r3
|
||||
and r0,r3 /* r3 = (4 - align_offset) % 4 */
|
||||
tst r3,r3 /* already aligned? */
|
||||
bt .end_b1 /* yes: skip leading byte loop */
|
||||
|
||||
add r5,r3 /* r3 = first source long bound */
|
||||
|
||||
/* leading byte loop: copies 0..3 bytes */
|
||||
.loop_b1:
|
||||
mov.b @r5+,r0 /* load byte & increment source addr */
|
||||
add #1,r4 /* increment dest addr */
|
||||
mov.b r0,@(7,r4) /* store byte */
|
||||
cmp/hi r5,r3 /* runs r5 up to first long bound */
|
||||
bt .loop_b1
|
||||
/* now r5 is always at a long boundary */
|
||||
/* -> memory reading is done in longs for all dest alignments */
|
||||
|
||||
/* selector for main copy loop */
|
||||
.end_b1:
|
||||
mov #3,r1
|
||||
and r4,r1 /* r1 = dest alignment offset */
|
||||
mova .jmptab,r0
|
||||
mov.b @(r0,r1),r1 /* select appropriate main loop */
|
||||
add r0,r1
|
||||
mov r6,r3 /* move end address to r3 */
|
||||
jmp @r1 /* and jump to it */
|
||||
add #-7,r3 /* adjust end addr for main loops doing 2 longs/pass */
|
||||
|
||||
/** main loops, copying 2 longs per pass to profit from fast page mode **/
|
||||
|
||||
/* long aligned destination (fastest) */
|
||||
.align 2
|
||||
.loop_do0:
|
||||
mov.l @r5+,r1 /* load first long & increment source addr */
|
||||
add #16,r4 /* increment dest addr & account for decrementing stores */
|
||||
mov.l @r5+,r0 /* load second long & increment source addr */
|
||||
cmp/hi r5,r3 /* runs r5 up to last or second last long bound */
|
||||
mov.l r0,@-r4 /* store second long */
|
||||
mov.l r1,@-r4 /* store first long; NOT ALIGNED - no speed loss here! */
|
||||
bt .loop_do0
|
||||
|
||||
add #4,r3 /* readjust end address */
|
||||
cmp/hi r5,r3 /* one long left? */
|
||||
bf .start_b2 /* no, jump to trailing byte loop */
|
||||
|
||||
mov.l @r5+,r0 /* load last long & increment source addr */
|
||||
add #4,r4 /* increment dest addr */
|
||||
bra .start_b2 /* jump to trailing byte loop */
|
||||
mov.l r0,@(4,r4) /* store last long */
|
||||
|
||||
/* word aligned destination (long + 2) */
|
||||
.align 2
|
||||
.loop_do2:
|
||||
mov.l @r5+,r1 /* load first long & increment source addr */
|
||||
add #16,r4 /* increment dest addr */
|
||||
mov.l @r5+,r0 /* load second long & increment source addr */
|
||||
cmp/hi r5,r3 /* runs r5 up to last or second last long bound */
|
||||
mov.w r0,@-r4 /* store low word of second long */
|
||||
xtrct r1,r0 /* extract low word of first long & high word of second long */
|
||||
mov.l r0,@-r4 /* and store as long */
|
||||
swap.w r1,r0 /* get high word of first long */
|
||||
mov.w r0,@-r4 /* and store it */
|
||||
bt .loop_do2
|
||||
|
||||
add #4,r3 /* readjust end address */
|
||||
cmp/hi r5,r3 /* one long left? */
|
||||
bf .start_b2 /* no, jump to trailing byte loop */
|
||||
|
||||
mov.l @r5+,r0 /* load last long & increment source addr */
|
||||
add #4,r4 /* increment dest addr */
|
||||
mov.w r0,@(6,r4) /* store low word */
|
||||
shlr16 r0 /* get high word */
|
||||
bra .start_b2 /* jump to trailing byte loop */
|
||||
mov.w r0,@(4,r4) /* and store it */
|
||||
|
||||
/* jumptable for loop selector */
|
||||
.align 2
|
||||
.jmptab:
|
||||
.byte .loop_do0 - .jmptab /* placed in the middle because the SH1 */
|
||||
.byte .loop_do1 - .jmptab /* loads bytes sign-extended. Otherwise */
|
||||
.byte .loop_do2 - .jmptab /* the last loop would be out of reach */
|
||||
.byte .loop_do3 - .jmptab /* of the offset range. */
|
||||
|
||||
/* byte aligned destination (long + 1) */
|
||||
.align 2
|
||||
.loop_do1:
|
||||
mov.l @r5+,r1 /* load first long & increment source addr */
|
||||
add #16,r4 /* increment dest addr */
|
||||
mov.l @r5+,r0 /* load second long & increment source addr */
|
||||
cmp/hi r5,r3 /* runs r5 up to last or second last long bound */
|
||||
mov.b r0,@-r4 /* store low byte of second long */
|
||||
shlr8 r0 /* get upper 3 bytes */
|
||||
mov r1,r2 /* copy first long */
|
||||
shll16 r2 /* move low byte of first long all the way up, .. */
|
||||
shll8 r2
|
||||
or r2,r0 /* ..combine with the 3 bytes of second long.. */
|
||||
mov.l r0,@-r4 /* ..and store as long */
|
||||
shlr8 r1 /* get middle 2 bytes */
|
||||
mov.w r1,@-r4 /* store as word */
|
||||
shlr16 r1 /* get upper byte */
|
||||
mov.b r1,@-r4 /* and store */
|
||||
bt .loop_do1
|
||||
|
||||
add #4,r3 /* readjust end address */
|
||||
.last_do13:
|
||||
cmp/hi r5,r3 /* one long left? */
|
||||
bf .start_b2 /* no, jump to trailing byte loop */
|
||||
|
||||
mov.l @r5+,r0 /* load last long & increment source addr */
|
||||
add #12,r4 /* increment dest addr */
|
||||
mov.b r0,@-r4 /* store low byte */
|
||||
shlr8 r0 /* get middle 2 bytes */
|
||||
mov.w r0,@-r4 /* store as word */
|
||||
shlr16 r0 /* get upper byte */
|
||||
mov.b r0,@-r4 /* and store */
|
||||
bra .start_b2 /* jump to trailing byte loop */
|
||||
add #-4,r4 /* readjust destination */
|
||||
|
||||
/* byte aligned destination (long + 3) */
|
||||
.align 2
|
||||
.loop_do3:
|
||||
mov.l @r5+,r1 /* load first long & increment source addr */
|
||||
add #16,r4 /* increment dest addr */
|
||||
mov.l @r5+,r0 /* load second long & increment source addr */
|
||||
mov r1,r2 /* copy first long */
|
||||
mov.b r0,@-r4 /* store low byte of second long */
|
||||
shlr8 r0 /* get middle 2 bytes */
|
||||
mov.w r0,@-r4 /* store as word */
|
||||
shlr16 r0 /* get upper byte */
|
||||
shll8 r2 /* move lower 3 bytes of first long one up.. */
|
||||
or r2,r0 /* ..combine with the 1 byte of second long.. */
|
||||
mov.l r0,@-r4 /* ..and store as long */
|
||||
shlr16 r1 /* get upper byte of first long.. */
|
||||
shlr8 r1
|
||||
cmp/hi r5,r3 /* runs r5 up to last or second last long bound */
|
||||
mov.b r1,@-r4 /* ..and store */
|
||||
bt .loop_do3
|
||||
|
||||
bra .last_do13 /* handle last longword: reuse routine for (long + 1) */
|
||||
add #4,r3 /* readjust end address */
|
||||
|
||||
/* trailing byte loop: copies 0..3 bytes (or all for < 11 in total) */
|
||||
.align 2
|
||||
.loop_b2:
|
||||
mov.b @r5+,r0 /* load byte & increment source addr */
|
||||
add #1,r4 /* increment dest addr */
|
||||
mov.b r0,@(7,r4) /* store byte */
|
||||
.start_b2:
|
||||
cmp/hi r5,r6 /* runs r5 up to end address */
|
||||
bt .loop_b2
|
||||
|
||||
rts
|
||||
mov r7,r0 /* return dest start address */
|
||||
.end:
|
||||
.size _memcpy,.end-_memcpy
|
||||
.size _mempcpy,.end-_mempcpy
|
||||
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _memmove
|
||||
.type _memmove,@function
|
||||
|
||||
/* Moves <length> bytes of data in memory from <source> to <dest>
|
||||
* Regions may overlap.
|
||||
* This version is optimized for speed, and needs the corresponding memcpy
|
||||
* implementation for the forward copy branch.
|
||||
*
|
||||
* arguments:
|
||||
* r4 - destination address
|
||||
* r5 - source address
|
||||
* r6 - length
|
||||
*
|
||||
* return value:
|
||||
* r0 - destination address (like ANSI version)
|
||||
*
|
||||
* register usage:
|
||||
* r0 - data / scratch
|
||||
* r1 - 2nd data / scratch
|
||||
* r2 - scratch
|
||||
* r3 - last long bound / adjusted start address (only if >= 11 bytes)
|
||||
* r4 - current dest address
|
||||
* r5 - source start address
|
||||
* r6 - current source address
|
||||
*
|
||||
* The instruction order is devised in a way to utilize the pipelining
|
||||
* of the SH1 to the max. The routine also tries to utilize fast page mode.
|
||||
*/
|
||||
|
||||
_memmove:
|
||||
cmp/hi r4,r5 /* source > destination */
|
||||
bf .backward /* no: backward copy */
|
||||
mov.l .memcpy_fwd,r0
|
||||
jmp @r0
|
||||
mov r4,r7 /* store dest for returning */
|
||||
|
||||
.align 2
|
||||
.memcpy_fwd:
|
||||
.long ___memcpy_fwd_entry
|
||||
|
||||
.backward:
|
||||
add r6,r4 /* r4 = destination end */
|
||||
mov #11,r0
|
||||
cmp/hs r0,r6 /* at least 11 bytes to copy? (ensures 2 aligned longs) */
|
||||
add #-8,r5 /* adjust for late decrement (max. 2 longs) */
|
||||
add r5,r6 /* r6 = source end - 8 */
|
||||
bf .start_b2r /* no: jump directly to byte loop */
|
||||
|
||||
mov #-4,r3 /* r3 = 0xfffffffc */
|
||||
and r6,r3 /* r3 = last source long bound */
|
||||
cmp/hi r3,r6 /* already aligned? */
|
||||
bf .end_b1r /* yes: skip leading byte loop */
|
||||
|
||||
.loop_b1r:
|
||||
mov.b @(7,r6),r0 /* load byte */
|
||||
add #-1,r6 /* decrement source addr */
|
||||
mov.b r0,@-r4 /* store byte */
|
||||
cmp/hi r3,r6 /* runs r6 down to last long bound */
|
||||
bt .loop_b1r
|
||||
|
||||
.end_b1r:
|
||||
mov #3,r1
|
||||
and r4,r1 /* r1 = dest alignment offset */
|
||||
mova .jmptab_r,r0
|
||||
mov.b @(r0,r1),r1 /* select appropriate main loop.. */
|
||||
add r0,r1
|
||||
mov r5,r3 /* copy start adress to r3 */
|
||||
jmp @r1 /* ..and jump to it */
|
||||
add #7,r3 /* adjust end addr for main loops doing 2 longs/pass */
|
||||
|
||||
/** main loops, copying 2 longs per pass to profit from fast page mode **/
|
||||
|
||||
/* long aligned destination (fastest) */
|
||||
.align 2
|
||||
.loop_do0r:
|
||||
mov.l @r6,r1 /* load first long */
|
||||
add #-8,r6 /* decrement source addr */
|
||||
mov.l @(12,r6),r0 /* load second long */
|
||||
cmp/hi r3,r6 /* runs r6 down to first or second long bound */
|
||||
mov.l r0,@-r4 /* store second long */
|
||||
mov.l r1,@-r4 /* store first long; NOT ALIGNED - no speed loss here! */
|
||||
bt .loop_do0r
|
||||
|
||||
add #-4,r3 /* readjust end address */
|
||||
cmp/hi r3,r6 /* first long left? */
|
||||
bf .start_b2r /* no, jump to trailing byte loop */
|
||||
|
||||
mov.l @(4,r6),r0 /* load first long */
|
||||
add #-4,r6 /* decrement source addr */
|
||||
bra .start_b2r /* jump to trailing byte loop */
|
||||
mov.l r0,@-r4 /* store first long */
|
||||
|
||||
/* word aligned destination (long + 2) */
|
||||
.align 2
|
||||
.loop_do2r:
|
||||
mov.l @r6,r1 /* load first long */
|
||||
add #-8,r6 /* decrement source addr */
|
||||
mov.l @(12,r6),r0 /* load second long */
|
||||
cmp/hi r3,r6 /* runs r6 down to first or second long bound */
|
||||
mov.w r0,@-r4 /* store low word of second long */
|
||||
xtrct r1,r0 /* extract low word of first long & high word of second long */
|
||||
mov.l r0,@-r4 /* and store as long */
|
||||
shlr16 r1 /* get high word of first long */
|
||||
mov.w r1,@-r4 /* and store it */
|
||||
bt .loop_do2r
|
||||
|
||||
add #-4,r3 /* readjust end address */
|
||||
cmp/hi r3,r6 /* first long left? */
|
||||
bf .start_b2r /* no, jump to trailing byte loop */
|
||||
|
||||
mov.l @(4,r6),r0 /* load first long & decrement source addr */
|
||||
add #-4,r6 /* decrement source addr */
|
||||
mov.w r0,@-r4 /* store low word */
|
||||
shlr16 r0 /* get high word */
|
||||
bra .start_b2r /* jump to trailing byte loop */
|
||||
mov.w r0,@-r4 /* and store it */
|
||||
|
||||
/* jumptable for loop selector */
|
||||
.align 2
|
||||
.jmptab_r:
|
||||
.byte .loop_do0r - .jmptab_r /* placed in the middle because the SH1 */
|
||||
.byte .loop_do1r - .jmptab_r /* loads bytes sign-extended. Otherwise */
|
||||
.byte .loop_do2r - .jmptab_r /* the last loop would be out of reach */
|
||||
.byte .loop_do3r - .jmptab_r /* of the offset range. */
|
||||
|
||||
/* byte aligned destination (long + 1) */
|
||||
.align 2
|
||||
.loop_do1r:
|
||||
mov.l @r6,r1 /* load first long */
|
||||
add #-8,r6 /* decrement source addr */
|
||||
mov.l @(12,r6),r0 /* load second long */
|
||||
cmp/hi r3,r6 /* runs r6 down to first or second long bound */
|
||||
mov.b r0,@-r4 /* store low byte of second long */
|
||||
shlr8 r0 /* get upper 3 bytes */
|
||||
mov r1,r2 /* copy first long */
|
||||
shll16 r2 /* move low byte of first long all the way up, .. */
|
||||
shll8 r2
|
||||
or r2,r0 /* ..combine with the 3 bytes of second long.. */
|
||||
mov.l r0,@-r4 /* ..and store as long */
|
||||
shlr8 r1 /* get middle 2 bytes */
|
||||
mov.w r1,@-r4 /* store as word */
|
||||
shlr16 r1 /* get upper byte */
|
||||
mov.b r1,@-r4 /* and store */
|
||||
bt .loop_do1r
|
||||
|
||||
add #-4,r3 /* readjust end address */
|
||||
.last_do13r:
|
||||
cmp/hi r3,r6 /* first long left? */
|
||||
bf .start_b2r /* no, jump to trailing byte loop */
|
||||
|
||||
nop /* alignment */
|
||||
mov.l @(4,r6),r0 /* load first long */
|
||||
add #-4,r6 /* decrement source addr */
|
||||
mov.b r0,@-r4 /* store low byte */
|
||||
shlr8 r0 /* get middle 2 bytes */
|
||||
mov.w r0,@-r4 /* store as word */
|
||||
shlr16 r0 /* get upper byte */
|
||||
bra .start_b2r /* jump to trailing byte loop */
|
||||
mov.b r0,@-r4 /* and store */
|
||||
|
||||
/* byte aligned destination (long + 3) */
|
||||
.align 2
|
||||
.loop_do3r:
|
||||
mov.l @r6,r1 /* load first long */
|
||||
add #-8,r6 /* decrement source addr */
|
||||
mov.l @(12,r6),r0 /* load second long */
|
||||
mov r1,r2 /* copy first long */
|
||||
mov.b r0,@-r4 /* store low byte of second long */
|
||||
shlr8 r0 /* get middle 2 bytes */
|
||||
mov.w r0,@-r4 /* store as word */
|
||||
shlr16 r0 /* get upper byte */
|
||||
shll8 r2 /* move lower 3 bytes of first long one up.. */
|
||||
or r2,r0 /* ..combine with the 1 byte of second long.. */
|
||||
mov.l r0,@-r4 /* ..and store as long */
|
||||
shlr16 r1 /* get upper byte of first long */
|
||||
shlr8 r1
|
||||
cmp/hi r3,r6 /* runs r6 down to first or second long bound */
|
||||
mov.b r1,@-r4 /* ..and store */
|
||||
bt .loop_do3r
|
||||
|
||||
bra .last_do13r /* handle first longword: reuse routine for (long + 1) */
|
||||
add #-4,r3 /* readjust end address */
|
||||
|
||||
/* trailing byte loop: copies 0..3 bytes (or all for < 11 in total) */
|
||||
.align 2
|
||||
.loop_b2r:
|
||||
mov.b @(7,r6),r0 /* load byte */
|
||||
add #-1,r6 /* decrement source addr */
|
||||
mov.b r0,@-r4 /* store byte */
|
||||
.start_b2r:
|
||||
cmp/hi r5,r6 /* runs r6 down to start address */
|
||||
bt .loop_b2r
|
||||
|
||||
rts
|
||||
mov r4,r0 /* return dest start address */
|
||||
.end:
|
||||
.size _memmove,.end-_memmove
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _memset
|
||||
.type _memset,@function
|
||||
|
||||
/* Fills a memory region with specified byte value
|
||||
* This version is optimized for speed
|
||||
*
|
||||
* arguments:
|
||||
* r4 - start address
|
||||
* r5 - data
|
||||
* r6 - length
|
||||
*
|
||||
* return value:
|
||||
* r0 - start address (like ANSI version)
|
||||
*
|
||||
* register usage:
|
||||
* r0 - temporary
|
||||
* r1 - start address +11 for main loop
|
||||
* r4 - start address
|
||||
* r5 - data (spread to all 4 bytes when using long stores)
|
||||
* r6 - current address (runs down from end to start)
|
||||
*
|
||||
* The instruction order below is devised in a way to utilize the pipelining
|
||||
* of the SH1 to the max. The routine fills memory from end to start in
|
||||
* order to utilize the auto-decrementing store instructions.
|
||||
*/
|
||||
|
||||
_memset:
|
||||
neg r4,r0
|
||||
and #3,r0 /* r0 = (4 - align_offset) % 4 */
|
||||
add #4,r0
|
||||
cmp/hs r0,r6 /* at least one aligned longword to fill? */
|
||||
add r4,r6 /* r6 = end_address */
|
||||
bf .no_longs /* no, jump directly to byte loop */
|
||||
|
||||
extu.b r5,r5 /* start: spread data to all 4 bytes */
|
||||
swap.b r5,r0
|
||||
or r0,r5 /* data now in 2 lower bytes of r5 */
|
||||
swap.w r5,r0
|
||||
or r0,r5 /* data now in all 4 bytes of r5 */
|
||||
|
||||
mov r6,r0
|
||||
tst #3,r0 /* r0 already long aligned? */
|
||||
bt .end_b1 /* yes: skip loop */
|
||||
|
||||
/* leading byte loop: sets 0..3 bytes */
|
||||
.loop_b1:
|
||||
mov.b r5,@-r0 /* store byte */
|
||||
tst #3,r0 /* r0 long aligned? */
|
||||
bf .loop_b1 /* runs r0 down until long aligned */
|
||||
|
||||
mov r0,r6 /* r6 = last long bound */
|
||||
nop /* keep alignment */
|
||||
|
||||
.end_b1:
|
||||
mov r4,r1 /* r1 = start_address... */
|
||||
add #11,r1 /* ... + 11, combined for rounding and offset */
|
||||
xor r1,r0
|
||||
tst #4,r0 /* bit 2 tells whether an even or odd number of */
|
||||
bf .loop_odd /* longwords to set */
|
||||
|
||||
/* main loop: set 2 longs per pass */
|
||||
.loop_2l:
|
||||
mov.l r5,@-r6 /* store first long */
|
||||
.loop_odd:
|
||||
cmp/hi r1,r6 /* runs r6 down to first long bound */
|
||||
mov.l r5,@-r6 /* store second long */
|
||||
bt .loop_2l
|
||||
|
||||
.no_longs:
|
||||
cmp/hi r4,r6 /* any bytes left? */
|
||||
bf .end_b2 /* no: skip loop */
|
||||
|
||||
/* trailing byte loop */
|
||||
.loop_b2:
|
||||
mov.b r5,@-r6 /* store byte */
|
||||
cmp/hi r4,r6 /* runs r6 down to the start address */
|
||||
bt .loop_b2
|
||||
|
||||
.end_b2:
|
||||
rts
|
||||
mov r4,r0 /* return start address */
|
||||
|
||||
.end:
|
||||
.size _memset,.end-_memset
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _strlen
|
||||
.type _strlen,@function
|
||||
|
||||
/* Works out the length of a string
|
||||
* This version is optimized for speed
|
||||
*
|
||||
* arguments:
|
||||
* r4 - start address
|
||||
*
|
||||
* return value:
|
||||
* r0 - string length
|
||||
*
|
||||
* register usage:
|
||||
* r0 - current address
|
||||
* r1 - current value (byte/long)
|
||||
* r2 - mask for alignment / zero (for cmp/str)
|
||||
* r4 - start address
|
||||
*
|
||||
*/
|
||||
|
||||
_strlen:
|
||||
mov r4,r0 /* r0 = start address */
|
||||
tst #3,r0 /* long aligned? */
|
||||
bt .start_l /* yes, jump directly to the longword loop */
|
||||
|
||||
/* not long aligned: check the first 3 bytes */
|
||||
mov.b @r0+,r1 /* fetch first byte */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
mov.b @r0+,r1 /* fetch second byte */
|
||||
mov #3,r2 /* prepare mask: r2 = 0..00000011b */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
mov.b @r0+,r1 /* fetch third byte */
|
||||
not r2,r2 /* prepare mask: r2 = 1..11111100b */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
|
||||
/* not yet found, fall through into longword loop */
|
||||
and r2,r0 /* align down to long bound */
|
||||
|
||||
/* main loop: check longwords */
|
||||
.start_l:
|
||||
mov #0,r2 /* zero longword for cmp/str */
|
||||
.loop_l:
|
||||
mov.l @r0+,r1 /* fetch long word */
|
||||
cmp/str r1,r2 /* any zero byte within? */
|
||||
bf .loop_l /* no, loop */
|
||||
add #-4,r0 /* set address back to start of this longword */
|
||||
|
||||
/* the last longword contains the string end: figure out the byte */
|
||||
mov.b @r0+,r1 /* fetch first byte */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
mov.b @r0+,r1 /* fetch second byte */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
mov.b @r0+,r1 /* fetch third byte */
|
||||
tst r1,r1 /* byte == 0 ? */
|
||||
bt .hitzero /* yes, string end found */
|
||||
rts /* must be the fourth byte */
|
||||
sub r4,r0 /* len = string_end - string_start */
|
||||
|
||||
.hitzero:
|
||||
add #-1,r0 /* undo address increment */
|
||||
rts
|
||||
sub r4,r0 /* len = string_end - string_start */
|
||||
|
||||
.end:
|
||||
.size _strlen,.end-_strlen
|
||||
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Ulf Ralberg
|
||||
*
|
||||
* SH processor threading support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Start the thread running and terminate it if it returns
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
void start_thread(void); /* Provide C access to ASM label */
|
||||
static void USED_ATTR __start_thread(void)
|
||||
{
|
||||
/* r8 = context */
|
||||
asm volatile (
|
||||
"_start_thread: \n" /* Start here - no naked attribute */
|
||||
"mov.l @(4, r8), r0 \n" /* Fetch thread function pointer */
|
||||
"mov.l @(28, r8), r15 \n" /* Set initial sp */
|
||||
"mov #0, r1 \n" /* Start the thread */
|
||||
"jsr @r0 \n"
|
||||
"mov.l r1, @(36, r8) \n" /* Clear start address */
|
||||
);
|
||||
thread_exit();
|
||||
}
|
||||
|
||||
/* Place context pointer in r8 slot, function pointer in r9 slot, and
|
||||
* start_thread pointer in context_start */
|
||||
#define THREAD_STARTUP_INIT(core, thread, function) \
|
||||
({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \
|
||||
(thread)->context.r[1] = (uint32_t)(function), \
|
||||
(thread)->context.start = (uint32_t)start_thread; })
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Store non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static inline void store_context(void* addr)
|
||||
{
|
||||
asm volatile (
|
||||
"add #36, %0 \n" /* Start at last reg. By the time routine */
|
||||
"sts.l pr, @-%0 \n" /* is done, %0 will have the original value */
|
||||
"mov.l r15,@-%0 \n"
|
||||
"mov.l r14,@-%0 \n"
|
||||
"mov.l r13,@-%0 \n"
|
||||
"mov.l r12,@-%0 \n"
|
||||
"mov.l r11,@-%0 \n"
|
||||
"mov.l r10,@-%0 \n"
|
||||
"mov.l r9, @-%0 \n"
|
||||
"mov.l r8, @-%0 \n"
|
||||
: : "r" (addr)
|
||||
);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Load non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static inline void load_context(const void* addr)
|
||||
{
|
||||
asm volatile (
|
||||
"mov.l @(36, %0), r0 \n" /* Get start address */
|
||||
"tst r0, r0 \n"
|
||||
"bt .running \n" /* NULL -> already running */
|
||||
"jmp @r0 \n" /* r8 = context */
|
||||
".running: \n"
|
||||
"mov.l @%0+, r8 \n" /* Executes in delay slot and outside it */
|
||||
"mov.l @%0+, r9 \n"
|
||||
"mov.l @%0+, r10 \n"
|
||||
"mov.l @%0+, r11 \n"
|
||||
"mov.l @%0+, r12 \n"
|
||||
"mov.l @%0+, r13 \n"
|
||||
"mov.l @%0+, r14 \n"
|
||||
"mov.l @%0+, r15 \n"
|
||||
"lds.l @%0+, pr \n"
|
||||
: : "r" (addr) : "r0" /* only! */
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Ulf Ralberg
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct regs
|
||||
{
|
||||
uint32_t r[7]; /* 0-24 - Registers r8 thru r14 */
|
||||
uint32_t sp; /* 28 - Stack pointer (r15) */
|
||||
uint32_t pr; /* 32 - Procedure register */
|
||||
uint32_t start; /* 36 - Thread start address, or NULL when started */
|
||||
};
|
||||
|
||||
#define DEFAULT_STACK_SIZE 0x400 /* Bytes */
|
||||
|
|
@ -9,8 +9,6 @@
|
|||
#include "arm/thread.c"
|
||||
#elif defined(CPU_COLDFIRE)
|
||||
#include "m68k/thread.c"
|
||||
#elif CONFIG_CPU == SH7034
|
||||
#include "sh/thread.c"
|
||||
#elif defined(CPU_MIPS)
|
||||
#include "mips/thread.c"
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -47,8 +47,6 @@ struct regs
|
|||
#include "arm/thread.h"
|
||||
#elif defined(CPU_COLDFIRE)
|
||||
#include "m68k/thread.h"
|
||||
#elif CONFIG_CPU == SH7034
|
||||
#include "sh/thread.h"
|
||||
#elif defined(CPU_MIPS)
|
||||
#include "mips/thread.h"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@
|
|||
|
||||
/* for internal functions' scanning use to save quite a bit of stack space -
|
||||
access must be serialized by the writer lock */
|
||||
#if defined(CPU_SH) || defined(IAUDIO_M5) \
|
||||
|| CONFIG_CPU == IMX233
|
||||
#if defined(IAUDIO_M5) || CONFIG_CPU == IMX233
|
||||
/* otherwise, out of IRAM */
|
||||
struct fat_direntry dir_fatent;
|
||||
#else
|
||||
|
|
|
|||
193
firmware/debug.c
193
firmware/debug.c
|
|
@ -30,9 +30,6 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
static char debugmembuf[200];
|
||||
#if CONFIG_CPU == SH7034
|
||||
static char debugbuf[400];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "kernel.h"
|
||||
|
|
@ -40,194 +37,6 @@ static char debugbuf[400];
|
|||
#include "debug.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#if CONFIG_CPU == SH7034 /* these are still very SH-oriented */
|
||||
void debug_init(void)
|
||||
{
|
||||
/* Clear it all! */
|
||||
SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER);
|
||||
|
||||
/* This enables the serial Rx interrupt, to be able to exit into the
|
||||
debugger when you hit CTRL-C */
|
||||
SCR1 |= 0x40;
|
||||
SCR1 &= ~0x80;
|
||||
IPRE |= 0xf000; /* Set to highest priority */
|
||||
}
|
||||
|
||||
static int debug_tx_ready(void)
|
||||
{
|
||||
return (SSR1 & SCI_TDRE);
|
||||
}
|
||||
|
||||
static void debug_tx_char(char ch)
|
||||
{
|
||||
while (!debug_tx_ready())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data into TDR and clear TDRE
|
||||
*/
|
||||
TDR1 = ch;
|
||||
SSR1 &= ~SCI_TDRE;
|
||||
}
|
||||
|
||||
static void debug_handle_error(char ssr)
|
||||
{
|
||||
(void)ssr;
|
||||
SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
|
||||
}
|
||||
|
||||
static int debug_rx_ready(void)
|
||||
{
|
||||
char ssr;
|
||||
|
||||
ssr = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
|
||||
if ( ssr )
|
||||
debug_handle_error ( ssr );
|
||||
return SSR1 & SCI_RDRF;
|
||||
}
|
||||
|
||||
static char debug_rx_char(void)
|
||||
{
|
||||
char ch;
|
||||
char ssr;
|
||||
|
||||
while (!debug_rx_ready())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
ch = RDR1;
|
||||
SSR1 &= ~SCI_RDRF;
|
||||
|
||||
ssr = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
|
||||
|
||||
if (ssr)
|
||||
debug_handle_error (ssr);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
static const char hexchars[] = "0123456789abcdef";
|
||||
|
||||
static char highhex(int x)
|
||||
{
|
||||
return hexchars[(x >> 4) & 0xf];
|
||||
}
|
||||
|
||||
static char lowhex(int x)
|
||||
{
|
||||
return hexchars[x & 0xf];
|
||||
}
|
||||
|
||||
static void putpacket (const char *buffer)
|
||||
{
|
||||
register int checksum;
|
||||
|
||||
const char *src = buffer;
|
||||
|
||||
/* Special debug hack. Shut off the Rx IRQ during I/O to prevent the debug
|
||||
stub from interrupting the message */
|
||||
SCR1 &= ~0x40;
|
||||
|
||||
debug_tx_char ('$');
|
||||
checksum = 0;
|
||||
|
||||
while (*src)
|
||||
{
|
||||
int runlen;
|
||||
|
||||
/* Do run length encoding */
|
||||
for (runlen = 0; runlen < 100; runlen ++)
|
||||
{
|
||||
if (src[0] != src[runlen] || runlen == 99)
|
||||
{
|
||||
if (runlen > 3)
|
||||
{
|
||||
int encode;
|
||||
/* Got a useful amount */
|
||||
debug_tx_char (*src);
|
||||
checksum += *src;
|
||||
debug_tx_char ('*');
|
||||
checksum += '*';
|
||||
checksum += (encode = runlen + ' ' - 4);
|
||||
debug_tx_char (encode);
|
||||
src += runlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_tx_char (*src);
|
||||
checksum += *src;
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
debug_tx_char ('#');
|
||||
debug_tx_char (highhex(checksum));
|
||||
debug_tx_char (lowhex(checksum));
|
||||
|
||||
/* Wait for the '+' */
|
||||
debug_rx_char();
|
||||
|
||||
/* Special debug hack. Enable the IRQ again */
|
||||
SCR1 |= 0x40;
|
||||
}
|
||||
|
||||
|
||||
/* convert the memory, pointed to by mem into hex, placing result in buf */
|
||||
/* return a pointer to the last char put in buf (null) */
|
||||
static char *mem2hex (const char *mem, char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
int ch;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ch = *mem++;
|
||||
*buf++ = highhex (ch);
|
||||
*buf++ = lowhex (ch);
|
||||
}
|
||||
*buf = 0;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static void debug(const char *msg)
|
||||
{
|
||||
debugbuf[0] = 'O';
|
||||
|
||||
mem2hex(msg, &debugbuf[1], strlen(msg));
|
||||
putpacket(debugbuf);
|
||||
}
|
||||
#elif defined(HAVE_GDB_API)
|
||||
static void *get_api_function(int n)
|
||||
{
|
||||
struct gdb_api *api = (struct gdb_api *)GDB_API_ADDRESS;
|
||||
if (api->magic == GDB_API_MAGIC)
|
||||
return api->func[n];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void breakpoint(void)
|
||||
{
|
||||
void (*f)(void) = get_api_function(0);
|
||||
if (f) (*f)();
|
||||
}
|
||||
|
||||
static void debug(char *msg)
|
||||
{
|
||||
void (*f)(char *) = get_api_function(1);
|
||||
if (f) (*f)(msg);
|
||||
}
|
||||
|
||||
void debug_init(void)
|
||||
{
|
||||
}
|
||||
#else /* !SH7034 && !HAVE_GDB_API */
|
||||
void debug_init(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -236,8 +45,6 @@ static inline void debug(char *msg)
|
|||
{
|
||||
(void)msg;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of DEBUG section */
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
|
|
|||
|
|
@ -1,285 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Driver for MAS35xx audio codec
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2007 by Christian Gmeiner
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h" /* MAX MIN macros */
|
||||
#include "sound.h"
|
||||
|
||||
int channel_configuration = SOUND_CHAN_STEREO;
|
||||
int stereo_width = 100;
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
unsigned long mdb_shape_shadow = 0;
|
||||
unsigned long loudness_shadow = 0;
|
||||
unsigned long shadow_io_control_main;
|
||||
#endif
|
||||
|
||||
static void set_channel_config(void)
|
||||
{
|
||||
/* default values: stereo */
|
||||
unsigned long val_ll = 0x80000;
|
||||
unsigned long val_lr = 0;
|
||||
unsigned long val_rl = 0;
|
||||
unsigned long val_rr = 0x80000;
|
||||
int bank;
|
||||
|
||||
switch(channel_configuration)
|
||||
{
|
||||
/* case SOUND_CHAN_STEREO unnecessary */
|
||||
|
||||
case SOUND_CHAN_MONO:
|
||||
val_ll = 0xc0000;
|
||||
val_lr = 0xc0000;
|
||||
val_rl = 0xc0000;
|
||||
val_rr = 0xc0000;
|
||||
break;
|
||||
|
||||
case SOUND_CHAN_CUSTOM:
|
||||
{
|
||||
/* fixed point variables (matching MAS internal format)
|
||||
integer part: upper 13 bits (inlcuding sign)
|
||||
fractional part: lower 19 bits */
|
||||
long fp_width, fp_straight, fp_cross;
|
||||
|
||||
fp_width = (stereo_width << 19) / 100;
|
||||
if (stereo_width <= 100)
|
||||
{
|
||||
fp_straight = - ((1<<19) + fp_width) / 2;
|
||||
fp_cross = fp_straight + fp_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* straight = - (1 + width) / (2 * width) */
|
||||
fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
|
||||
fp_cross = (1<<19) + fp_straight;
|
||||
}
|
||||
val_ll = val_rr = fp_straight & 0xfffff;
|
||||
val_lr = val_rl = fp_cross & 0xfffff;
|
||||
}
|
||||
break;
|
||||
|
||||
case SOUND_CHAN_MONO_LEFT:
|
||||
val_ll = 0x80000;
|
||||
val_lr = 0x80000;
|
||||
val_rl = 0;
|
||||
val_rr = 0;
|
||||
break;
|
||||
|
||||
case SOUND_CHAN_MONO_RIGHT:
|
||||
val_ll = 0;
|
||||
val_lr = 0;
|
||||
val_rl = 0x80000;
|
||||
val_rr = 0x80000;
|
||||
break;
|
||||
|
||||
case SOUND_CHAN_KARAOKE:
|
||||
val_ll = 0xc0000;
|
||||
val_lr = 0x40000;
|
||||
val_rl = 0x40000;
|
||||
val_rr = 0xc0000;
|
||||
break;
|
||||
}
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
bank = MAS_BANK_D0;
|
||||
#elif CONFIG_CODEC == MAS3507D
|
||||
bank = MAS_BANK_D1;
|
||||
#endif
|
||||
|
||||
mas_writemem(bank, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
|
||||
mas_writemem(bank, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
|
||||
mas_writemem(bank, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
|
||||
mas_writemem(bank, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
|
||||
}
|
||||
|
||||
void audiohw_set_channel(int val)
|
||||
{
|
||||
channel_configuration = val;
|
||||
set_channel_config();
|
||||
}
|
||||
|
||||
void audiohw_set_stereo_width(int val)
|
||||
{
|
||||
stereo_width = val;
|
||||
if (channel_configuration == SOUND_CHAN_CUSTOM) {
|
||||
set_channel_config();
|
||||
}
|
||||
}
|
||||
|
||||
void audiohw_set_bass(int val)
|
||||
{
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8;
|
||||
mas_codec_writereg(MAS_REG_KBASS, tmp);
|
||||
#elif CONFIG_CODEC == MAS3507D
|
||||
mas_writereg(MAS_REG_KBASS, bass_table[val+15]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
void audiohw_set_prescaler(int val)
|
||||
{
|
||||
mas_writereg(MAS_REG_KPRESCALE, prescale_table[val/10]);
|
||||
}
|
||||
#endif
|
||||
|
||||
void audiohw_set_treble(int val)
|
||||
{
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
unsigned tmp = ((unsigned)(val * 8) & 0xff) << 8;
|
||||
mas_codec_writereg(MAS_REG_KTREBLE, tmp);
|
||||
#elif CONFIG_CODEC == MAS3507D
|
||||
mas_writereg(MAS_REG_KTREBLE, treble_table[val+15]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (CONFIG_CODEC == MAS3507D)
|
||||
/* convert tenth of dB volume (-780..+180) to dac3550 register value */
|
||||
static unsigned int tenthdb2reg(int db)
|
||||
{
|
||||
if (db < -540) /* 3 dB steps */
|
||||
return (db + 780) / 30;
|
||||
else /* 1.5 dB steps */
|
||||
return (db + 660) / 15;
|
||||
}
|
||||
|
||||
void audiohw_set_volume(int vol_l, int vol_r)
|
||||
{
|
||||
dac_volume(tenthdb2reg(vol_l), tenthdb2reg(vol_r), false);
|
||||
}
|
||||
#endif /* CONFIG_CODEC == MAS3507D */
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
void audiohw_set_volume(int val)
|
||||
{
|
||||
unsigned tmp = ((unsigned)(val + 115) & 0xff) << 8;
|
||||
mas_codec_writereg(MAS_REG_VOLUME_CONTROL, tmp);
|
||||
}
|
||||
|
||||
void audiohw_set_loudness(int value)
|
||||
{
|
||||
loudness_shadow = (loudness_shadow & 0x04) |
|
||||
(MAX(MIN(value * 4, 0x44), 0) << 8);
|
||||
mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
|
||||
}
|
||||
|
||||
void audiohw_set_avc(int value)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
static const uint16_t avc_vals[] =
|
||||
{
|
||||
(0x1 << 8) | (0x8 << 12), /* 20ms */
|
||||
(0x2 << 8) | (0x8 << 12), /* 2s */
|
||||
(0x4 << 8) | (0x8 << 12), /* 4s */
|
||||
(0x8 << 8) | (0x8 << 12), /* 8s */
|
||||
};
|
||||
switch (value) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
tmp = avc_vals[value -1];
|
||||
break;
|
||||
case -1: /* turn off and then turn on again to decay quickly */
|
||||
tmp = mas_codec_readreg(MAS_REG_KAVC);
|
||||
mas_codec_writereg(MAS_REG_KAVC, 0);
|
||||
break;
|
||||
default: /* off */
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
mas_codec_writereg(MAS_REG_KAVC, tmp);
|
||||
}
|
||||
|
||||
void audiohw_set_mdb_strength(int value)
|
||||
{
|
||||
mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
|
||||
}
|
||||
|
||||
void audiohw_set_mdb_harmonics(int value)
|
||||
{
|
||||
int tmp = value * 127 / 100;
|
||||
mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
|
||||
}
|
||||
|
||||
void audiohw_set_mdb_center(int value)
|
||||
{
|
||||
mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
|
||||
}
|
||||
|
||||
void audiohw_set_mdb_shape(int value)
|
||||
{
|
||||
mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
|
||||
mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
|
||||
}
|
||||
|
||||
void audiohw_set_mdb_enable(int value)
|
||||
{
|
||||
mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
|
||||
mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
|
||||
}
|
||||
|
||||
void audiohw_set_superbass(int value)
|
||||
{
|
||||
loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
|
||||
mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
|
||||
}
|
||||
|
||||
void audiohw_set_balance(int val)
|
||||
{
|
||||
unsigned tmp = ((unsigned)(val * 127 / 100) & 0xff) << 8;
|
||||
mas_codec_writereg(MAS_REG_BALANCE, tmp);
|
||||
}
|
||||
|
||||
/* This functionality works by telling the decoder that we have another
|
||||
crystal frequency than we actually have. It will adjust its internal
|
||||
parameters and the result is that the audio is played at another pitch.
|
||||
*/
|
||||
static int32_t last_pitch = PITCH_SPEED_100;
|
||||
|
||||
void audiohw_set_pitch(int32_t val)
|
||||
{
|
||||
if (val == last_pitch)
|
||||
return;
|
||||
|
||||
/* Calculate the new (bogus) frequency */
|
||||
unsigned long reg = 18432 * PITCH_SPEED_100 / val;
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, ®, 1);
|
||||
|
||||
/* We must tell the MAS that the frequency has changed.
|
||||
* This will unfortunately cause a short silence. */
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN,
|
||||
&shadow_io_control_main, 1);
|
||||
|
||||
last_pitch = val;
|
||||
}
|
||||
|
||||
int32_t audiohw_get_pitch(void)
|
||||
{
|
||||
return last_pitch;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */
|
||||
|
||||
|
|
@ -134,25 +134,3 @@ unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate,
|
|||
unsigned int type)
|
||||
{ return samplerate; (void)type; }
|
||||
#endif /* CONFIG_SAMPR_TYPES */
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
int mas_codec_readreg(int reg)
|
||||
{
|
||||
(void)reg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mas_codec_writereg(int reg, unsigned int val)
|
||||
{
|
||||
(void)reg;
|
||||
(void)val;
|
||||
return 0;
|
||||
}
|
||||
int mas_writemem(int bank, int addr, const unsigned long* src, int len)
|
||||
{
|
||||
(void)bank;
|
||||
(void)addr;
|
||||
(void)src;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -575,9 +575,6 @@ static int button_flip(int button)
|
|||
#if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD)
|
||||
| BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD
|
||||
#endif
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
| BUTTON_F1 | BUTTON_F3
|
||||
#endif
|
||||
#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
|
||||
(CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
||||
| BUTTON_VOL_UP | BUTTON_VOL_DOWN
|
||||
|
|
@ -604,12 +601,6 @@ static int button_flip(int button)
|
|||
if (button & BUTTON_SCROLL_FWD)
|
||||
newbutton |= BUTTON_SCROLL_BACK;
|
||||
#endif
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
if (button & BUTTON_F1)
|
||||
newbutton |= BUTTON_F3;
|
||||
if (button & BUTTON_F3)
|
||||
newbutton |= BUTTON_F1;
|
||||
#endif
|
||||
#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
|
||||
(CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
||||
if (button & BUTTON_VOL_UP)
|
||||
|
|
|
|||
|
|
@ -1,121 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "lcd.h"
|
||||
#include "sh7034.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "debug.h"
|
||||
#include "system.h"
|
||||
#include "fmradio.h"
|
||||
|
||||
#if CONFIG_TUNER
|
||||
|
||||
/* Signals:
|
||||
DI (Data In) - PB0 (doubles as data pin for the LCD)
|
||||
CL (Clock) - PB1 (doubles as clock for the LCD)
|
||||
CE (Chip Enable) - PB3 (also chip select for the LCD, but active low)
|
||||
DO (Data Out) - PB4
|
||||
*/
|
||||
|
||||
/* cute little functions */
|
||||
#define CE_LO and_b(~0x08, PBDRL_ADDR)
|
||||
#define CE_HI or_b(0x08, PBDRL_ADDR)
|
||||
#define CL_LO and_b(~0x02, PBDRL_ADDR)
|
||||
#define CL_HI or_b(0x02, PBDRL_ADDR)
|
||||
#define DO (PBDR & 0x10)
|
||||
#define DI_LO and_b(~0x01, PBDRL_ADDR)
|
||||
#define DI_HI or_b(0x01, PBDRL_ADDR)
|
||||
|
||||
#define START or_b((0x08 | 0x02), PBDRL_ADDR)
|
||||
|
||||
/* delay loop */
|
||||
#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0)
|
||||
|
||||
|
||||
int fmradio_read(int addr)
|
||||
{
|
||||
int i;
|
||||
int data = 0;
|
||||
|
||||
START;
|
||||
|
||||
/* First address bit */
|
||||
CL_LO;
|
||||
if(addr & 2)
|
||||
DI_HI;
|
||||
else
|
||||
DI_LO;
|
||||
DELAY;
|
||||
CL_HI;
|
||||
DELAY;
|
||||
|
||||
/* Second address bit */
|
||||
CL_LO;
|
||||
if(addr & 1)
|
||||
DI_HI;
|
||||
else
|
||||
DI_LO;
|
||||
DELAY;
|
||||
CL_HI;
|
||||
DELAY;
|
||||
|
||||
for(i = 0; i < 21;i++)
|
||||
{
|
||||
CL_LO;
|
||||
DELAY;
|
||||
data <<= 1;
|
||||
data |= (DO)?1:0;
|
||||
CL_HI;
|
||||
DELAY;
|
||||
}
|
||||
|
||||
CE_LO;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void fmradio_set(int addr, int data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Include the address in the data */
|
||||
data |= addr << 21;
|
||||
|
||||
START;
|
||||
|
||||
for(i = 0; i < 23;i++)
|
||||
{
|
||||
CL_LO;
|
||||
DELAY;
|
||||
if(data & (1 << 22))
|
||||
DI_HI;
|
||||
else
|
||||
DI_LO;
|
||||
|
||||
data <<= 1;
|
||||
CL_HI;
|
||||
DELAY;
|
||||
}
|
||||
|
||||
CE_LO;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "i2c.h"
|
||||
#include "rtc.h"
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "timefuncs.h"
|
||||
|
||||
#define RTC_ADR 0xd0
|
||||
#define RTC_DEV_WRITE (RTC_ADR | 0x00)
|
||||
#define RTC_DEV_READ (RTC_ADR | 0x01)
|
||||
|
||||
void rtc_init(void)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
#ifdef HAVE_RTC_ALARM
|
||||
/* Check + save alarm bit first, before the power thread starts watching */
|
||||
rtc_check_alarm_started(false);
|
||||
#endif
|
||||
|
||||
/* Clear the Stop bit if it is set */
|
||||
data = rtc_read(0x01);
|
||||
if(data & 0x80)
|
||||
rtc_write(0x01, 0x00);
|
||||
|
||||
/* Clear the HT bit if it is set */
|
||||
data = rtc_read(0x0c);
|
||||
|
||||
if(data & 0x40)
|
||||
{
|
||||
data &= ~0x40;
|
||||
rtc_write(0x0c,data);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RTC_ALARM
|
||||
|
||||
/* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */
|
||||
/* without this, the alarm won't work! */
|
||||
|
||||
data = rtc_read(0x04);
|
||||
if (data & 0x80)
|
||||
{
|
||||
data &= ~0x80;
|
||||
rtc_write(0x04, data);
|
||||
}
|
||||
|
||||
/* Also, make sure that the OUT bit in register 8 is 1,
|
||||
otherwise the player can't be turned off. */
|
||||
rtc_write(8, rtc_read(8) | 0x80);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_RTC_ALARM
|
||||
|
||||
/* check whether the unit has been started by the RTC alarm function */
|
||||
/* (check for AF, which => started using wakeup alarm) */
|
||||
bool rtc_check_alarm_started(bool release_alarm)
|
||||
{
|
||||
static bool alarm_state, run_before;
|
||||
bool rc;
|
||||
|
||||
if (run_before) {
|
||||
rc = alarm_state;
|
||||
alarm_state &= ~release_alarm;
|
||||
} else {
|
||||
/* This call resets AF, so we store the state for later recall */
|
||||
rc = alarm_state = rtc_check_alarm_flag();
|
||||
run_before = true;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
* Checks the AL register. This call resets AL once read.
|
||||
*
|
||||
* We're only interested if ABE is set. AL is still raised regardless
|
||||
* even if the unit is off when the alarm occurs.
|
||||
*/
|
||||
bool rtc_check_alarm_flag(void)
|
||||
{
|
||||
return ( ( (rtc_read(0x0f) & 0x40) != 0) &&
|
||||
(rtc_read(0x0a) & 0x20) );
|
||||
}
|
||||
|
||||
/* set alarm time registers to the given time (repeat once per day) */
|
||||
void rtc_set_alarm(int h, int m)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
/* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */
|
||||
|
||||
rtc_write(0x0e, 0x00); /* seconds 0 and RTP1 */
|
||||
rtc_write(0x0d, DEC2BCD(m)); /* minutes and RPT2 */
|
||||
rtc_write(0x0c, DEC2BCD(h)); /* hour and RPT3 */
|
||||
rtc_write(0x0b, 0xc1); /* set date 01 and RPT4 and RTP5 */
|
||||
|
||||
/* set month to 1, if it's invalid, the rtc does an alarm every second instead */
|
||||
data = rtc_read(0x0a);
|
||||
data &= 0xe0;
|
||||
data |= 0x01;
|
||||
rtc_write(0x0a, data);
|
||||
}
|
||||
|
||||
/* read out the current alarm time */
|
||||
void rtc_get_alarm(int *h, int *m)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
data = rtc_read(0x0c);
|
||||
*h = BCD2DEC(data & 0x3f);
|
||||
|
||||
data = rtc_read(0x0d);
|
||||
*m = BCD2DEC(data & 0x7f);
|
||||
}
|
||||
|
||||
/* turn alarm on or off by setting the alarm flag enable */
|
||||
/* the alarm is automatically disabled when the RTC gets Vcc power at startup */
|
||||
/* avoid that an alarm occurs when the device is on because this locks the ON key forever */
|
||||
void rtc_enable_alarm(bool enable)
|
||||
{
|
||||
unsigned char data = rtc_read(0x0a);
|
||||
if (enable)
|
||||
{
|
||||
data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */
|
||||
}
|
||||
else
|
||||
data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */
|
||||
rtc_write(0x0a, data);
|
||||
|
||||
/* check if alarm flag AF is off (as it should be) */
|
||||
/* in some cases enabling the alarm results in an activated AF flag */
|
||||
/* this should not happen, but it does */
|
||||
/* if you know why, tell me! */
|
||||
/* for now, we try again forever in this case */
|
||||
while (rtc_check_alarm_flag()) /* on */
|
||||
{
|
||||
data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */
|
||||
rtc_write(0x0a, data);
|
||||
sleep(HZ / 10);
|
||||
rtc_check_alarm_flag();
|
||||
data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */
|
||||
rtc_write(0x0a, data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_RTC_ALARM */
|
||||
|
||||
int rtc_write(unsigned char address, unsigned char value)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[2];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = address;
|
||||
buf[1] = value;
|
||||
|
||||
/* send run command */
|
||||
if (i2c_write(RTC_DEV_WRITE,buf,2))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtc_read(unsigned char address)
|
||||
{
|
||||
int value = -1;
|
||||
unsigned char buf[1];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = address;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(RTC_DEV_READ,buf,1) >= 0)
|
||||
{
|
||||
i2c_start();
|
||||
i2c_outb(RTC_DEV_READ);
|
||||
if (i2c_getack())
|
||||
{
|
||||
value = i2c_inb(1);
|
||||
}
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
|
||||
i2c_end();
|
||||
return value;
|
||||
}
|
||||
|
||||
int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char obuf[1];
|
||||
int i;
|
||||
|
||||
i2c_begin();
|
||||
|
||||
obuf[0] = address;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(RTC_DEV_READ, obuf, 1) >= 0)
|
||||
{
|
||||
i2c_start();
|
||||
i2c_outb(RTC_DEV_READ);
|
||||
if (i2c_getack())
|
||||
{
|
||||
for(i = 0;i < numbytes-1;i++)
|
||||
buf[i] = i2c_inb(0);
|
||||
|
||||
buf[i] = i2c_inb(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtc_read_datetime(struct tm *tm)
|
||||
{
|
||||
int rc;
|
||||
unsigned char buf[7];
|
||||
|
||||
rc = rtc_read_multiple(1, buf, sizeof(buf));
|
||||
|
||||
/* convert from bcd, avoid getting extra bits */
|
||||
tm->tm_sec = BCD2DEC(buf[0] & 0x7f);
|
||||
tm->tm_min = BCD2DEC(buf[1] & 0x7f);
|
||||
tm->tm_hour = BCD2DEC(buf[2] & 0x3f);
|
||||
tm->tm_mday = BCD2DEC(buf[4] & 0x3f);
|
||||
tm->tm_mon = BCD2DEC(buf[5] & 0x1f) - 1;
|
||||
tm->tm_year = BCD2DEC(buf[6]) + 100;
|
||||
tm->tm_yday = 0; /* Not implemented for now */
|
||||
|
||||
set_day_of_week(tm);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int rtc_write_datetime(const struct tm *tm)
|
||||
{
|
||||
unsigned int i;
|
||||
int rc = 0;
|
||||
unsigned char buf[7];
|
||||
|
||||
buf[0] = tm->tm_sec;
|
||||
buf[1] = tm->tm_min;
|
||||
buf[2] = tm->tm_hour;
|
||||
buf[3] = tm->tm_wday;
|
||||
buf[4] = tm->tm_mday;
|
||||
buf[5] = tm->tm_mon + 1;
|
||||
buf[6] = tm->tm_year - 100;
|
||||
|
||||
/* Adjust weekday */
|
||||
if (buf[3] == 0)
|
||||
buf[3] = 7;
|
||||
|
||||
for (i = 0; i < sizeof(buf) ;i++)
|
||||
{
|
||||
rc |= rtc_write(i + 1, DEC2BCD(buf[i]));
|
||||
}
|
||||
rc |= rtc_write(8, 0x80); /* Out=1, calibration = 0 */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
* Tuner "middleware" for Samsung S1A0903X01 chip
|
||||
*
|
||||
* Copyright (C) 2003 Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "kernel.h"
|
||||
#include "tuner.h" /* tuner abstraction interface */
|
||||
#include "fmradio.h" /* physical interface driver */
|
||||
#include "sound.h"
|
||||
#include "mas35xx.h"
|
||||
#include "power.h"
|
||||
|
||||
#define DEFAULT_IN1 0x100003 /* Mute */
|
||||
#define DEFAULT_IN2 0x140884 /* 5kHz, 7.2MHz crystal */
|
||||
#define PLL_FREQ_STEP 10000
|
||||
|
||||
static int fm_in1;
|
||||
static int fm_in2;
|
||||
static int fm_present = -1; /* unknown */
|
||||
|
||||
/* tuner abstraction layer: set something to the tuner */
|
||||
int s1a0903x01_set(int setting, int value)
|
||||
{
|
||||
int val = 1;
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_SLEEP:
|
||||
if (!value)
|
||||
{
|
||||
tuner_power(true);
|
||||
/* wakeup: just unit */
|
||||
fm_in1 = DEFAULT_IN1;
|
||||
fm_in2 = DEFAULT_IN2;
|
||||
fmradio_set(1, fm_in1);
|
||||
fmradio_set(2, fm_in2);
|
||||
}
|
||||
else
|
||||
tuner_power(false);
|
||||
/* else we have no sleep mode? */
|
||||
break;
|
||||
|
||||
case RADIO_FREQUENCY:
|
||||
{
|
||||
int pll_cnt;
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
/* Shift the MAS internal clock away for certain frequencies to
|
||||
* avoid interference. */
|
||||
int pitch = 1000;
|
||||
|
||||
/* 4th harmonic falls in the FM frequency range */
|
||||
int if_freq = 4 * mas_get_pllfreq();
|
||||
|
||||
/* shift the mas harmonic >= 300 kHz away using the direction
|
||||
* which needs less shifting. */
|
||||
if (value < if_freq)
|
||||
{
|
||||
if (if_freq - value < 300000)
|
||||
pitch = 1003 - (if_freq - value) / 100000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value - if_freq < 300000)
|
||||
pitch = 997 + (value - if_freq) / 100000;
|
||||
}
|
||||
sound_set_pitch(pitch);
|
||||
#endif
|
||||
/* We add the standard Intermediate Frequency 10.7MHz
|
||||
** before calculating the divisor
|
||||
** The reference frequency is set to 50kHz, and the VCO
|
||||
** output is prescaled by 2.
|
||||
*/
|
||||
|
||||
pll_cnt = (value + 10700000) / (PLL_FREQ_STEP/2) / 2;
|
||||
|
||||
/* 0x100000 == FM mode
|
||||
** 0x000002 == Microprocessor controlled Mute
|
||||
*/
|
||||
fm_in1 = (fm_in1 & 0xfff00007) | (pll_cnt << 3);
|
||||
fmradio_set(1, fm_in1);
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_SCAN_FREQUENCY:
|
||||
/* Tune in and delay */
|
||||
s1a0903x01_set(RADIO_FREQUENCY, value);
|
||||
sleep(1);
|
||||
/* Start IF measurement */
|
||||
fm_in1 |= 4;
|
||||
fmradio_set(1, fm_in1);
|
||||
sleep(1);
|
||||
val = s1a0903x01_get(RADIO_TUNED);
|
||||
break;
|
||||
|
||||
case RADIO_MUTE:
|
||||
fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0);
|
||||
fmradio_set(1, fm_in1);
|
||||
break;
|
||||
|
||||
case RADIO_FORCE_MONO:
|
||||
fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4);
|
||||
fmradio_set(2, fm_in2);
|
||||
break;
|
||||
/* NOTE: These were only zeroed when starting the tuner from OFF
|
||||
but the default values already set them to 0. */
|
||||
#if 0
|
||||
case S1A0903X01_IF_MEASUREMENT:
|
||||
fm_in1 = (fm_in1 & 0xfffffffb) | (value?4:0);
|
||||
fmradio_set(1, fm_in1);
|
||||
break;
|
||||
|
||||
case S1A0903X01_SENSITIVITY:
|
||||
fm_in2 = (fm_in2 & 0xffff9fff) | ((value & 3) << 13);
|
||||
fmradio_set(2, fm_in2);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
val = -1;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* tuner abstraction layer: read something from the tuner */
|
||||
int s1a0903x01_get(int setting)
|
||||
{
|
||||
int val = -1;
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_PRESENT:
|
||||
if (fm_present == -1)
|
||||
{
|
||||
#ifdef HAVE_TUNER_PWR_CTRL
|
||||
bool fmstatus = tuner_power(true);
|
||||
#endif
|
||||
/* 5kHz, 7.2MHz crystal, test mode 1 */
|
||||
fmradio_set(2, 0x140885);
|
||||
fm_present = (fmradio_read(0) == 0x140885);
|
||||
#ifdef HAVE_TUNER_PWR_CTRL
|
||||
if (!fmstatus)
|
||||
tuner_power(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
val = fm_present;
|
||||
break;
|
||||
|
||||
case RADIO_TUNED:
|
||||
val = fmradio_read(3);
|
||||
val = abs(10700 - ((val & 0x7ffff) / 8)) < 50; /* convert to kHz */
|
||||
break;
|
||||
|
||||
case RADIO_STEREO:
|
||||
val = fmradio_read(3);
|
||||
val = ((val & 0x100000) ? true : false);
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
|
@ -184,8 +184,6 @@ struct sound_settings_info
|
|||
#include "tlv320.h"
|
||||
#elif defined(HAVE_AS3514)
|
||||
#include "as3514.h"
|
||||
#elif defined(HAVE_MAS35XX)
|
||||
#include "mas35xx.h"
|
||||
#if defined(HAVE_DAC3550A)
|
||||
#include "dac3550a.h"
|
||||
#endif /* HAVE_DAC3550A */
|
||||
|
|
|
|||
|
|
@ -84,16 +84,6 @@ AUDIOHW_SETTINGS(
|
|||
AUDIOHW_SETTING_ENT(BALANCE, sound_set_balance)
|
||||
AUDIOHW_SETTING_ENT(CHANNELS, sound_set_channels)
|
||||
AUDIOHW_SETTING_ENT(STEREO_WIDTH, sound_set_stereo_width)
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
AUDIOHW_SETTING_ENT(LOUDNESS, sound_set_loudness)
|
||||
AUDIOHW_SETTING_ENT(AVC, sound_set_avc)
|
||||
AUDIOHW_SETTING_ENT(MDB_STRENGTH, sound_set_mdb_strength)
|
||||
AUDIOHW_SETTING_ENT(MDB_HARMONICS, sound_set_mdb_harmonics)
|
||||
AUDIOHW_SETTING_ENT(MDB_CENTER, sound_set_mdb_center)
|
||||
AUDIOHW_SETTING_ENT(MDB_SHAPE, sound_set_mdb_shape)
|
||||
AUDIOHW_SETTING_ENT(MDB_ENABLE, sound_set_mdb_enable)
|
||||
AUDIOHW_SETTING_ENT(SUPERBASS, sound_set_superbass)
|
||||
#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
#if defined(AUDIOHW_HAVE_LIN_GAIN)
|
||||
AUDIOHW_SETTING_ENT(LEFT_GAIN, NULL)
|
||||
AUDIOHW_SETTING_ENT(RIGHT_GAIN, NULL)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#define STORAGE_HOSTFS (1 << STORAGE_HOSTFS_NUM)
|
||||
|
||||
/* CONFIG_TUNER (note these are combineable bit-flags) */
|
||||
#define S1A0903X01 0x01 /* Samsung */
|
||||
#define TEA5767 0x02 /* Philips */
|
||||
#define LV24020LP 0x04 /* Sanyo */
|
||||
#define SI4700 0x08 /* Silicon Labs */
|
||||
|
|
@ -55,13 +54,9 @@
|
|||
#define STFM1000 0x100 /* Sigmatel */
|
||||
|
||||
/* CONFIG_CODEC */
|
||||
#define MAS3587F 3587
|
||||
#define MAS3507D 3507
|
||||
#define MAS3539F 3539
|
||||
#define SWCODEC 1 /* if codec is done by SW */
|
||||
|
||||
/* CONFIG_CPU */
|
||||
#define SH7034 7034
|
||||
#define MCF5249 5249
|
||||
#define MCF5250 5250
|
||||
#define PP5002 5002
|
||||
|
|
@ -103,9 +98,6 @@
|
|||
#define PLATFORM_PANDORA (1<<6)
|
||||
|
||||
/* CONFIG_KEYPAD */
|
||||
#define PLAYER_PAD 1
|
||||
#define RECORDER_PAD 2
|
||||
#define ONDIO_PAD 3
|
||||
#define IRIVER_H100_PAD 4
|
||||
#define IRIVER_H300_PAD 5
|
||||
#define IAUDIO_X5M5_PAD 6
|
||||
|
|
@ -222,8 +214,7 @@
|
|||
if the estimation is better that ours
|
||||
(which it probably is) */
|
||||
/* CONFIG_LCD */
|
||||
#define LCD_SSD1815 1 /* as used by Archos Recorders and Ondios */
|
||||
#define LCD_SSD1801 2 /* as used by Archos Player/Studio */
|
||||
#define LCD_SSD1815 1 /* as used by Sansa M200 and others */
|
||||
#define LCD_S1D15E06 3 /* as used by iRiver H100 series */
|
||||
#define LCD_H300 4 /* as used by iRiver H300 series, exact model name is
|
||||
unknown at the time of this writing */
|
||||
|
|
@ -312,8 +303,6 @@
|
|||
/* CONFIG_I2C */
|
||||
#define I2C_NONE 0 /* For targets that do not use I2C - as the
|
||||
Lyre prototype 1 */
|
||||
#define I2C_PLAYREC 1 /* Archos Player/Recorder style */
|
||||
#define I2C_ONDIO 2 /* Ondio style */
|
||||
#define I2C_COLDFIRE 3 /* Coldfire style */
|
||||
#define I2C_PP5002 4 /* PP5002 style */
|
||||
#define I2C_PP5020 5 /* PP5020 style */
|
||||
|
|
@ -345,7 +334,6 @@ Lyre prototype 1 */
|
|||
#define NAND_IMX233 6
|
||||
|
||||
/* CONFIG_RTC */
|
||||
#define RTC_M41ST84W 1 /* Archos Recorder */
|
||||
#define RTC_PCF50605 2 /* iPod 3G, 4G & Mini */
|
||||
#define RTC_PCF50606 3 /* iriver H300 */
|
||||
#define RTC_S3C2440 4
|
||||
|
|
@ -398,19 +386,7 @@ Lyre prototype 1 */
|
|||
#define IMX233_CREATIVE (1 << 1) /* Creative MBLK windowing */
|
||||
|
||||
/* now go and pick yours */
|
||||
#if defined(ARCHOS_PLAYER)
|
||||
#include "config/archosplayer.h"
|
||||
#elif defined(ARCHOS_RECORDER)
|
||||
#include "config/archosrecorder.h"
|
||||
#elif defined(ARCHOS_FMRECORDER)
|
||||
#include "config/archosfmrecorder.h"
|
||||
#elif defined(ARCHOS_RECORDERV2)
|
||||
#include "config/archosrecorderv2.h"
|
||||
#elif defined(ARCHOS_ONDIOSP)
|
||||
#include "config/archosondiosp.h"
|
||||
#elif defined(ARCHOS_ONDIOFM)
|
||||
#include "config/archosondiofm.h"
|
||||
#elif defined(IRIVER_H100)
|
||||
#if defined(IRIVER_H100)
|
||||
#include "config/iriverh100.h"
|
||||
#elif defined(IRIVER_H120)
|
||||
#include "config/iriverh120.h"
|
||||
|
|
@ -659,11 +635,6 @@ Lyre prototype 1 */
|
|||
|
||||
#ifndef __PCTOOL__
|
||||
|
||||
/* define for all cpus from SH family */
|
||||
#if (ARCH == ARCH_SH) && (CONFIG_CPU == SH7034)
|
||||
#define CPU_SH
|
||||
#endif
|
||||
|
||||
/* define for all cpus from coldfire family */
|
||||
#if (ARCH == ARCH_M68K) && ((CONFIG_CPU == MCF5249) || (CONFIG_CPU == MCF5250))
|
||||
#define CPU_COLDFIRE
|
||||
|
|
@ -932,11 +903,6 @@ Lyre prototype 1 */
|
|||
#define HAVE_PICTUREFLOW_INTEGRATION
|
||||
#endif
|
||||
|
||||
/* Add one HAVE_ define for all mas35xx targets */
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3507D) || (CONFIG_CODEC == MAS3539F)
|
||||
#define HAVE_MAS35XX
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == SWCODEC)
|
||||
#ifdef BOOTLOADER
|
||||
|
||||
|
|
@ -1012,7 +978,7 @@ Lyre prototype 1 */
|
|||
#endif /* (CONFIG_CODEC == SWCODEC) */
|
||||
|
||||
/* Determine if accesses should be strictly long aligned. */
|
||||
#if (CONFIG_CPU == SH7034) || defined(CPU_ARM) || defined(CPU_MIPS)
|
||||
#if defined(CPU_ARM) || defined(CPU_MIPS)
|
||||
#define ROCKBOX_STRICT_ALIGN 1
|
||||
#endif
|
||||
|
||||
|
|
@ -1061,8 +1027,7 @@ Lyre prototype 1 */
|
|||
|
||||
/* IRAM usage */
|
||||
#if (CONFIG_PLATFORM & PLATFORM_NATIVE) && /* Not for hosted environments */ \
|
||||
(((CONFIG_CPU == SH7034) && !defined(PLUGIN)) || /* SH1 archos: core only */ \
|
||||
defined(CPU_COLDFIRE) || /* Coldfire: core, plugins, codecs */ \
|
||||
(defined(CPU_COLDFIRE) || /* Coldfire: core, plugins, codecs */ \
|
||||
defined(CPU_PP) || /* PortalPlayer: core, plugins, codecs */ \
|
||||
(CONFIG_CPU == AS3525 && MEMORYSIZE > 2 && !defined(BOOTLOADER)) || /* AS3525 +2MB: core, plugins, codecs */ \
|
||||
(CONFIG_CPU == AS3525 && MEMORYSIZE <= 2 && !defined(PLUGIN) && !defined(CODEC) && !defined(BOOTLOADER)) || /* AS3525 2MB: core only */ \
|
||||
|
|
@ -1077,7 +1042,7 @@ Lyre prototype 1 */
|
|||
#define IDATA_ATTR __attribute__ ((section(".idata")))
|
||||
#define IBSS_ATTR __attribute__ ((section(".ibss")))
|
||||
#define USE_IRAM
|
||||
#if CONFIG_CPU != SH7034 && (CONFIG_CPU != AS3525 || MEMORYSIZE > 2) \
|
||||
#if (CONFIG_CPU != AS3525 || MEMORYSIZE > 2) \
|
||||
&& CONFIG_CPU != JZ4732 && CONFIG_CPU != JZ4760B && CONFIG_CPU != AS3525v2 && CONFIG_CPU != IMX233
|
||||
#define PLUGIN_USE_IRAM
|
||||
#endif
|
||||
|
|
@ -1283,8 +1248,7 @@ Lyre prototype 1 */
|
|||
#define HAVE_PCM_FULL_DUPLEX
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == SWCODEC) || (CONFIG_CODEC == MAS3587F) || \
|
||||
(CONFIG_CODEC == MAS3539F)
|
||||
#if (CONFIG_CODEC == SWCODEC)
|
||||
#define HAVE_PITCHCONTROL
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
/* define this if you use an ATA controller */
|
||||
#define CONFIG_STORAGE STORAGE_ATA
|
||||
|
||||
#define MODEL_NAME "Archos FM Recorder"
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
#define HAVE_RECORDING
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_SPDIF)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
#define HAVE_LCD_FLIP
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
#define HAVE_LCD_INVERT
|
||||
|
||||
/* define this if you have access to the quickscreen */
|
||||
#define HAVE_QUICKSCREEN
|
||||
|
||||
/* define this if you have the button bar */
|
||||
#define HAVE_BUTTONBAR
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 112
|
||||
#define LCD_HEIGHT 64
|
||||
/* sqrt(112^2 + 64^2) / 1.5 = 85.4 */
|
||||
#define LCD_DPI 85
|
||||
#define LCD_DEPTH 1
|
||||
|
||||
#define LCD_PIXEL_ASPECT_WIDTH 4
|
||||
#define LCD_PIXEL_ASPECT_HEIGHT 5
|
||||
|
||||
#define LCD_PIXELFORMAT VERTICAL_PACKING
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x7ee57e
|
||||
|
||||
/* define this if you have a Recorder style 10-key keyboard */
|
||||
#define CONFIG_KEYPAD RECORDER_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
#define HAVE_MORSE_INPUT
|
||||
|
||||
/* define this if you have a real-time clock */
|
||||
#define CONFIG_RTC RTC_M41ST84W
|
||||
|
||||
/* FM recorders can wake up from RTC alarm */
|
||||
#define HAVE_RTC_ALARM
|
||||
|
||||
/* define this if you have RTC RAM available for settings */
|
||||
#define HAVE_RTC_RAM
|
||||
|
||||
/* Define this if you have a software controlled poweroff */
|
||||
#define HAVE_SW_POWEROFF
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Define this if you have an FM Radio */
|
||||
#define CONFIG_TUNER S1A0903X01
|
||||
#endif
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
|
||||
/* Define this if you have a MAS3587F */
|
||||
#define CONFIG_CODEC MAS3587F
|
||||
|
||||
/* Define this for LCD backlight available */
|
||||
#define HAVE_BACKLIGHT
|
||||
|
||||
/* define this if you have a disk storage, i.e. something
|
||||
that needs spinups and can cause skips when shaked */
|
||||
#define HAVE_DISK_STORAGE
|
||||
|
||||
#define CONFIG_I2C I2C_PLAYREC
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 2200 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 2200 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
#define CURRENT_NORMAL 145 /* usual current in mA */
|
||||
#define CURRENT_RECORD 35 /* additional recording current */
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
|
||||
/* Hardware controlled charging with monitoring */
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this if you have a FM Recorder key system */
|
||||
#define HAVE_FMADC
|
||||
|
||||
/* Define this if battery voltage can only be measured with ATA powered */
|
||||
#define NEED_ATA_POWER_BATT_MEASURE
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 11059200
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 20
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 6
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 24
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
/* #define ROM_START 0x14010 for behind original Archos */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Software controlled LED */
|
||||
#define CONFIG_LED LED_REAL
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1815
|
||||
|
||||
#define BOOTFILE_EXT "ajz"
|
||||
#define BOOTFILE "ajbrec." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 63
|
||||
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
#define HAVE_HOTKEY
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/* define this if you have recording possibility */
|
||||
#define HAVE_RECORDING
|
||||
|
||||
#define MODEL_NAME "Ondio FM"
|
||||
|
||||
#define ONDIO_SERIES
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
#define HAVE_LCD_FLIP
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
#define HAVE_LCD_INVERT
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 112
|
||||
#define LCD_HEIGHT 64
|
||||
/* sqrt(112^2 + 64^2) / 1.5 = 83.8 */
|
||||
#define LCD_DPI 84
|
||||
#define LCD_DEPTH 1
|
||||
|
||||
#define LCD_PIXEL_ASPECT_WIDTH 4
|
||||
#define LCD_PIXEL_ASPECT_HEIGHT 5
|
||||
|
||||
#define LCD_PIXELFORMAT VERTICAL_PACKING
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x82b4fa
|
||||
|
||||
/* define this if you have an Ondio style 6-key keyboard */
|
||||
#define CONFIG_KEYPAD ONDIO_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
#define HAVE_MORSE_INPUT
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
#define ACTION_WPSAB_SINGLE ACTION_WPS_BROWSE
|
||||
|
||||
/* Define this if you have a software controlled poweroff */
|
||||
#define HAVE_SW_POWEROFF
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Define this if you have an FM Radio */
|
||||
#define CONFIG_TUNER (S1A0903X01 | TEA5767) /* to be decided at runtime */
|
||||
#define CONFIG_TUNER_XTAL 13000000
|
||||
#endif
|
||||
|
||||
/* Define this if you have a MAS3587F */
|
||||
#define CONFIG_CODEC MAS3587F
|
||||
|
||||
/* define this if you have a flash memory storage */
|
||||
#define HAVE_FLASH_STORAGE
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 1000 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 1500 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 2 /* Alkalines or NiMH */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
/* define this if the unit should not shut down on low battery. */
|
||||
#define NO_LOW_BATTERY_SHUTDOWN
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 95 /* average, nearly proportional to 1/U */
|
||||
#define CURRENT_USB 1 /* host powered in USB mode; avoid zero-div */
|
||||
#define CURRENT_BACKLIGHT 0 /* no backlight */
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 12000000
|
||||
|
||||
/* Define this for different I2C pinout */
|
||||
#define CONFIG_I2C I2C_ONDIO
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 20
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 6
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 24
|
||||
|
||||
/* Define this if the tuner is switched on by software */
|
||||
#define HAVE_TUNER_PWR_CTRL
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
/* #define ROM_START 0x16010 for behind original Archos */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Define this if the display is mounted upside down */
|
||||
#define HAVE_DISPLAY_FLIPPED
|
||||
|
||||
/* Define this for different ADC channel assignment */
|
||||
#define HAVE_ONDIO_ADC
|
||||
|
||||
/* Define this for MMC support instead of ATA harddisk */
|
||||
#define CONFIG_STORAGE STORAGE_MMC
|
||||
|
||||
/* Define this to support mounting FAT16 partitions */
|
||||
#define HAVE_FAT16SUPPORT
|
||||
|
||||
/* Define this if the MAS SIBI line can be controlled via PB8 */
|
||||
#define HAVE_MAS_SIBI_CONTROL
|
||||
|
||||
/* define this if more than one device/partition can be used */
|
||||
#define HAVE_MULTIDRIVE
|
||||
#define NUM_DRIVES 2
|
||||
|
||||
/* define this if media can be exchanged on the fly */
|
||||
#define HAVE_HOTSWAP
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1815
|
||||
|
||||
#define BOOTFILE_EXT "ajz"
|
||||
#define BOOTFILE "ajbrec." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 63
|
||||
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
//#define HAVE_HOTKEY
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
#define MODEL_NAME "Ondio SP"
|
||||
|
||||
#define ONDIO_SERIES
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
#define HAVE_LCD_FLIP
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
#define HAVE_LCD_INVERT
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 112
|
||||
#define LCD_HEIGHT 64
|
||||
/* sqrt(112^2 + 64^2) / 1.5 = 83.8 */
|
||||
#define LCD_DPI 84
|
||||
#define LCD_DEPTH 1
|
||||
|
||||
#define LCD_PIXEL_ASPECT_WIDTH 4
|
||||
#define LCD_PIXEL_ASPECT_HEIGHT 5
|
||||
|
||||
#define LCD_PIXELFORMAT VERTICAL_PACKING
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x82b4fa
|
||||
|
||||
/* define this if you have an Ondio style 6-key keyboard */
|
||||
#define CONFIG_KEYPAD ONDIO_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
#define HAVE_MORSE_INPUT
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
#define ACTION_WPSAB_SINGLE ACTION_WPS_BROWSE
|
||||
|
||||
/* Define this if you have a software controlled poweroff */
|
||||
#define HAVE_SW_POWEROFF
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
/* Define this if you have a MAS3539F */
|
||||
#define CONFIG_CODEC MAS3539F
|
||||
|
||||
/* define this if you have a flash memory storage */
|
||||
#define HAVE_FLASH_STORAGE
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 1000 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 1500 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 2 /* Alkalines or NiMH */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
/* define this if the unit should not shut down on low battery. */
|
||||
#define NO_LOW_BATTERY_SHUTDOWN
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 95 /* average, nearly proportional to 1/U */
|
||||
#define CURRENT_USB 1 /* host powered in USB mode; avoid zero-div */
|
||||
#define CURRENT_BACKLIGHT 0 /* no backlight */
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 12000000
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 20
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 6
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 24
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
/* #define ROM_START 0x12010 for behind original Archos */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Define this if the display is mounted upside down */
|
||||
#define HAVE_DISPLAY_FLIPPED
|
||||
|
||||
/* Define this for different I2C pinout */
|
||||
#define CONFIG_I2C I2C_ONDIO
|
||||
|
||||
/* Define this for different ADC channel assignment */
|
||||
#define HAVE_ONDIO_ADC
|
||||
|
||||
/* Define this for MMC support instead of ATA harddisk */
|
||||
#define CONFIG_STORAGE STORAGE_MMC
|
||||
|
||||
/* Define this to support mounting FAT16 partitions */
|
||||
#define HAVE_FAT16SUPPORT
|
||||
|
||||
/* Define this if the MAS SIBI line can be controlled via PB8 */
|
||||
#define HAVE_MAS_SIBI_CONTROL
|
||||
|
||||
/* define this if more than one device/partition can be used */
|
||||
#define HAVE_MULTIDRIVE
|
||||
#define NUM_DRIVES 2
|
||||
|
||||
/* define this if media can be exchanged on the fly */
|
||||
#define HAVE_HOTSWAP
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1815
|
||||
|
||||
#define BOOTFILE_EXT "ajz"
|
||||
#define BOOTFILE "ajbrec." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 63
|
||||
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
//#define HAVE_HOTKEY
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/* define this if you use an ATA controller */
|
||||
#define CONFIG_STORAGE STORAGE_ATA
|
||||
|
||||
#define MODEL_NAME "Archos Player/Studio"
|
||||
|
||||
/* define this if you have a charcell LCD display */
|
||||
#define HAVE_LCD_CHARCELLS
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
#define LCD_WIDTH 11
|
||||
#define LCD_HEIGHT 2
|
||||
/* sqrt(11^2 + 2^2) / 1.5 = 7.5 */
|
||||
#define LCD_DPI 7
|
||||
#define LCD_DEPTH 1
|
||||
#define SIM_LCD_WIDTH 132 /* pixels */
|
||||
#define SIM_LCD_HEIGHT 64 /* pixels */
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x7ee57e
|
||||
|
||||
/* define this if you have the Player's keyboard */
|
||||
#define CONFIG_KEYPAD PLAYER_PAD
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
#define ACTION_WPSAB_SINGLE ACTION_WPS_BROWSE
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
/* Define this if you have a MAS3507D */
|
||||
#define CONFIG_CODEC MAS3507D
|
||||
|
||||
/* Define this if you have a DAC3550A */
|
||||
#define HAVE_DAC3550A
|
||||
|
||||
/* define this if you have a disk storage, i.e. something
|
||||
that needs spinups and can cause skips when shaked */
|
||||
#define HAVE_DISK_STORAGE
|
||||
|
||||
/* Define this for LCD backlight available */
|
||||
#define HAVE_BACKLIGHT
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
#define CURRENT_NORMAL 145 /* usual current in mA */
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
|
||||
/* define this if the unit should not shut down on low battery. */
|
||||
#define NO_LOW_BATTERY_SHUTDOWN
|
||||
|
||||
/* Hardware controlled charging */
|
||||
#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this if you control ata power player style
|
||||
(with PB4, new player only) */
|
||||
#define ATA_POWER_PLAYERSTYLE
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 12000000 /* cycle time ~83.3ns */
|
||||
|
||||
/* Define this if you must discharge the data line by driving it low
|
||||
and then set it to input to see if it stays low or goes high */
|
||||
#define HAVE_I2C_LOW_FIRST
|
||||
|
||||
#define CONFIG_I2C I2C_PLAYREC
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 0
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 4
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 6
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Software controlled LED */
|
||||
#define CONFIG_LED LED_REAL
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1801
|
||||
|
||||
#define BOOTFILE_EXT "mod"
|
||||
#define BOOTFILE "archos." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 31
|
||||
#define DEFAULT_CONTRAST_SETTING 30
|
||||
|
||||
#define HAVE_SERIAL
|
||||
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
#define HAVE_HOTKEY
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
/* define this if you use an ATA controller */
|
||||
#define CONFIG_STORAGE STORAGE_ATA
|
||||
|
||||
#define MODEL_NAME "Archos Recorder"
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
#define HAVE_RECORDING
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_SPDIF)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
//#define HAVE_LCD_FLIP
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
#define HAVE_LCD_INVERT
|
||||
|
||||
/* define this if you have access to the quickscreen */
|
||||
#define HAVE_QUICKSCREEN
|
||||
|
||||
/* define this if you have the button bar */
|
||||
#define HAVE_BUTTONBAR
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 112
|
||||
#define LCD_HEIGHT 64
|
||||
/* sqrt(112^2 + 64^2) / 1.5 = 85.4 */
|
||||
#define LCD_DPI 85
|
||||
#define LCD_DEPTH 1
|
||||
|
||||
#define LCD_PIXEL_ASPECT_WIDTH 4
|
||||
#define LCD_PIXEL_ASPECT_HEIGHT 5
|
||||
|
||||
#define LCD_PIXELFORMAT VERTICAL_PACKING
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x7ee57e
|
||||
|
||||
/* define this if you have the Recorder's 10-key keyboard */
|
||||
#define CONFIG_KEYPAD RECORDER_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
//#define HAVE_MORSE_INPUT
|
||||
|
||||
/* define this if you have a real-time clock */
|
||||
#define CONFIG_RTC RTC_M41ST84W
|
||||
|
||||
/* define this if you have RTC RAM available for settings */
|
||||
#define HAVE_RTC_RAM
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
|
||||
/* Define this if you have a MAS3587F */
|
||||
#define CONFIG_CODEC MAS3587F
|
||||
|
||||
/* define this if you have a disk storage, i.e. something
|
||||
that needs spinups and can cause skips when shaked */
|
||||
#define HAVE_DISK_STORAGE
|
||||
|
||||
/* Define this for LCD backlight available */
|
||||
#define HAVE_BACKLIGHT
|
||||
|
||||
#define CONFIG_I2C I2C_PLAYREC
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 1500 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
#if MEMORYSIZE < 8
|
||||
#define CURRENT_NORMAL 145 /* usual current in mA */
|
||||
#else
|
||||
#define CURRENT_NORMAL 145 *100 / 122 /* assuming 192 kbps, the running time is 22% longer with 8MB */
|
||||
#endif
|
||||
#define CURRENT_RECORD 35 /* additional recording current */
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
|
||||
/* define this if the unit should not shut down on low battery. */
|
||||
#define NO_LOW_BATTERY_SHUTDOWN
|
||||
|
||||
/* Software controlled charging */
|
||||
#define CONFIG_CHARGING CHARGING_TARGET
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this if you have ATA power-off control */
|
||||
#define HAVE_ATA_POWER_OFF
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 11059200
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 0
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 4
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 6
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
/* #define ROM_START 0x11010 for behind original Archos */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Software controlled LED */
|
||||
#define CONFIG_LED LED_REAL
|
||||
|
||||
/* Define this for S/PDIF output available */
|
||||
#define HAVE_SPDIF_OUT
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1815
|
||||
|
||||
#define BOOTFILE_EXT "ajz"
|
||||
#define BOOTFILE "ajbrec." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 63
|
||||
|
||||
#define HAVE_SERIAL
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
#define HAVE_HOTKEY
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/* define this if you use an ATA controller */
|
||||
#define CONFIG_STORAGE STORAGE_ATA
|
||||
|
||||
#define MODEL_NAME "Archos Recorder v2"
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
#define HAVE_RECORDING
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_SPDIF)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
#define HAVE_LCD_FLIP
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
#define HAVE_LCD_INVERT
|
||||
|
||||
/* define this if you have access to the quickscreen */
|
||||
#define HAVE_QUICKSCREEN
|
||||
|
||||
/* define this if you have the button bar */
|
||||
#define HAVE_BUTTONBAR
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 112
|
||||
#define LCD_HEIGHT 64
|
||||
/* sqrt(112^2 + 64^2) / 1.5 = 85.4 */
|
||||
#define LCD_DPI 85
|
||||
#define LCD_DEPTH 1
|
||||
|
||||
#define LCD_PIXEL_ASPECT_WIDTH 4
|
||||
#define LCD_PIXEL_ASPECT_HEIGHT 5
|
||||
|
||||
#define LCD_PIXELFORMAT VERTICAL_PACKING
|
||||
|
||||
/* Display colours, for screenshots and sim (0xRRGGBB) */
|
||||
#define LCD_DARKCOLOR 0x000000
|
||||
#define LCD_BRIGHTCOLOR 0x5a915a
|
||||
#define LCD_BL_DARKCOLOR 0x000000
|
||||
#define LCD_BL_BRIGHTCOLOR 0x7ee57e
|
||||
|
||||
/* define this if you have a Recorder style 10-key keyboard */
|
||||
#define CONFIG_KEYPAD RECORDER_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
#define HAVE_MORSE_INPUT
|
||||
|
||||
/* define this if you have a real-time clock */
|
||||
#define CONFIG_RTC RTC_M41ST84W
|
||||
|
||||
/* FM recorders can wake up from RTC alarm */
|
||||
#define HAVE_RTC_ALARM
|
||||
|
||||
/* define this if you have RTC RAM available for settings */
|
||||
#define HAVE_RTC_RAM
|
||||
|
||||
/* Define this if you have a software controlled poweroff */
|
||||
#define HAVE_SW_POWEROFF
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x8000
|
||||
|
||||
#define AB_REPEAT_ENABLE
|
||||
|
||||
/* Define this if you have a MAS3587F */
|
||||
#define CONFIG_CODEC MAS3587F
|
||||
|
||||
/* define this if you have a disk storage, i.e. something
|
||||
that needs spinups and can cause skips when shaked */
|
||||
#define HAVE_DISK_STORAGE
|
||||
|
||||
/* Define this for LCD backlight available */
|
||||
#define HAVE_BACKLIGHT
|
||||
|
||||
#define CONFIG_I2C I2C_PLAYREC
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 2200 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 2200 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 50 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
|
||||
|
||||
#define CURRENT_NORMAL 145 /* usual current in mA */
|
||||
#define CURRENT_RECORD 35 /* additional recording current */
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
|
||||
/* Hardware controlled charging with monitoring */
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
#define CONFIG_CPU SH7034
|
||||
|
||||
/* Define this if you have a FM Recorder key system */
|
||||
#define HAVE_FMADC
|
||||
|
||||
/* Define this if battery voltage can only be measured with ATA powered */
|
||||
#define NEED_ATA_POWER_BATT_MEASURE
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 11059200
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file length */
|
||||
#define FIRMWARE_OFFSET_FILE_LENGTH 20
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the file CRC */
|
||||
#define FIRMWARE_OFFSET_FILE_CRC 6
|
||||
|
||||
/* Offset ( in the firmware file's header ) to the real data */
|
||||
#define FIRMWARE_OFFSET_FILE_DATA 24
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Define this if you have an FM Radio */
|
||||
#define CONFIG_TUNER S1A0903X01
|
||||
#endif
|
||||
|
||||
/* The start address index for ROM builds */
|
||||
/* #define ROM_START 0x12010 for behind original Archos */
|
||||
#define ROM_START 0x7010 /* for behind BootBox */
|
||||
|
||||
/* Software controlled LED */
|
||||
#define CONFIG_LED LED_REAL
|
||||
|
||||
#define CONFIG_LCD LCD_SSD1815
|
||||
|
||||
#define BOOTFILE_EXT "ajz"
|
||||
#define BOOTFILE "ajbrec." BOOTFILE_EXT
|
||||
#define BOOTDIR "/"
|
||||
|
||||
#define HAVE_LCD_CONTRAST
|
||||
|
||||
#define MIN_CONTRAST_SETTING 5
|
||||
#define MAX_CONTRAST_SETTING 63
|
||||
|
||||
/* Define this if a programmable hotkey is mapped */
|
||||
#define HAVE_HOTKEY
|
||||
|
|
@ -20,9 +20,6 @@
|
|||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
#if CONFIG_CPU == SH7034
|
||||
#include "sh7034.h"
|
||||
#endif
|
||||
#if CONFIG_CPU == MCF5249
|
||||
#include "mcf5249.h"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,37 +24,6 @@
|
|||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
#if (CONFIG_CPU == SH7034) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
||||
|
||||
#define ROM_VERSION (*(short *)0x020000fe)
|
||||
|
||||
/* Bit mask values for HW compatibility */
|
||||
#define ATA_ADDRESS_200 0x0100
|
||||
#define USB_ACTIVE_HIGH 0x0100
|
||||
#define PR_ACTIVE_HIGH 0x0100
|
||||
#define LCD_CONTRAST_BIAS 0x0200
|
||||
#define MMC_CLOCK_POLARITY 0x0400
|
||||
#define TUNER_MODEL 0x0800
|
||||
|
||||
#ifdef ARCHOS_PLAYER
|
||||
#define HW_MASK 0
|
||||
#else /* Recorders, Ondios */
|
||||
#define HW_MASK (*(short *)0x020000fc)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TUNER_MULTI
|
||||
static inline int tuner_detect_type(void)
|
||||
{
|
||||
return (HW_MASK & TUNER_MODEL) ? TEA5767 : S1A0903X01;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* (CONFIG_CPU == SH7034) && (CONFIG_PLATFORM & PLATFORM_NATIVE) */
|
||||
|
||||
#ifdef ARCHOS_PLAYER
|
||||
bool is_new_player(void);
|
||||
#endif
|
||||
|
||||
#ifdef IPOD_ARCH
|
||||
#ifdef IPOD_VIDEO
|
||||
#ifdef BOOTLOADER
|
||||
|
|
|
|||
|
|
@ -1,292 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Implementation of MAS35xx audiohw api driver.
|
||||
*
|
||||
* Copyright (C) 2007 by Christian Gmeiner
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _MAS35XX_H
|
||||
#define _MAS35XX_H
|
||||
|
||||
#include "config.h"
|
||||
#include "mascodec.h"
|
||||
|
||||
#define MAS_BANK_D0 0
|
||||
#define MAS_BANK_D1 1
|
||||
|
||||
/* registers common to all MAS35xx */
|
||||
#define MAS_REG_DCCF 0x8e
|
||||
#define MAS_REG_MUTE 0xaa
|
||||
#define MAS_REG_PIODATA 0xc8
|
||||
#define MAS_REG_StartUpConfig 0xe6
|
||||
#define MAS_REG_KPRESCALE 0xe7
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
|
||||
#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP)
|
||||
|
||||
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -78, 18, -18)
|
||||
AUDIOHW_SETTING(BASS, "dB", 0, 1, -15, 15, 7)
|
||||
AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -15, 15, 7)
|
||||
|
||||
/* I2C defines */
|
||||
#define MAS_ADR 0x3a
|
||||
#define MAS_DEV_WRITE (MAS_ADR | 0x00)
|
||||
#define MAS_DEV_READ (MAS_ADR | 0x01)
|
||||
|
||||
/* MAS3507D registers */
|
||||
#define MAS_DATA_WRITE 0x68
|
||||
#define MAS_DATA_READ 0x69
|
||||
#define MAS_CONTROL 0x6a
|
||||
|
||||
#define MAS_REG_KBASS 0x6b
|
||||
#define MAS_REG_KTREBLE 0x6f
|
||||
|
||||
/* MAS3507D commands */
|
||||
#define MAS_CMD_READ_ANCILLARY 0x30
|
||||
#define MAS_CMD_WRITE_REG 0x90
|
||||
#define MAS_CMD_WRITE_D0_MEM 0xa0
|
||||
#define MAS_CMD_WRITE_D1_MEM 0xb0
|
||||
#define MAS_CMD_READ_REG 0xd0
|
||||
#define MAS_CMD_READ_D0_MEM 0xe0
|
||||
#define MAS_CMD_READ_D1_MEM 0xf0
|
||||
|
||||
/* MAS3507D D0 memmory cells */
|
||||
#define MAS_D0_MPEG_FRAME_COUNT 0x300
|
||||
#define MAS_D0_MPEG_STATUS_1 0x301
|
||||
#define MAS_D0_MPEG_STATUS_2 0x302
|
||||
#define MAS_D0_CRC_ERROR_COUNT 0x303
|
||||
#define MAS_D0_OUT_LL 0x7f8
|
||||
#define MAS_D0_OUT_LR 0x7f9
|
||||
#define MAS_D0_OUT_RL 0x7fa
|
||||
#define MAS_D0_OUT_RR 0x7fb
|
||||
|
||||
static const unsigned int bass_table[] =
|
||||
{
|
||||
0x9e400, /* -15dB */
|
||||
0xa2800, /* -14dB */
|
||||
0xa7400, /* -13dB */
|
||||
0xac400, /* -12dB */
|
||||
0xb1800, /* -11dB */
|
||||
0xb7400, /* -10dB */
|
||||
0xbd400, /* -9dB */
|
||||
0xc3c00, /* -8dB */
|
||||
0xca400, /* -7dB */
|
||||
0xd1800, /* -6dB */
|
||||
0xd8c00, /* -5dB */
|
||||
0xe0400, /* -4dB */
|
||||
0xe8000, /* -3dB */
|
||||
0xefc00, /* -2dB */
|
||||
0xf7c00, /* -1dB */
|
||||
0,
|
||||
0x800, /* 1dB */
|
||||
0x10000, /* 2dB */
|
||||
0x17c00, /* 3dB */
|
||||
0x1f800, /* 4dB */
|
||||
0x27000, /* 5dB */
|
||||
0x2e400, /* 6dB */
|
||||
0x35800, /* 7dB */
|
||||
0x3c000, /* 8dB */
|
||||
0x42800, /* 9dB */
|
||||
0x48800, /* 10dB */
|
||||
0x4e400, /* 11dB */
|
||||
0x53800, /* 12dB */
|
||||
0x58800, /* 13dB */
|
||||
0x5d400, /* 14dB */
|
||||
0x61800 /* 15dB */
|
||||
};
|
||||
|
||||
static const unsigned int treble_table[] =
|
||||
{
|
||||
0xb2c00, /* -15dB */
|
||||
0xbb400, /* -14dB */
|
||||
0xc1800, /* -13dB */
|
||||
0xc6c00, /* -12dB */
|
||||
0xcbc00, /* -11dB */
|
||||
0xd0400, /* -10dB */
|
||||
0xd5000, /* -9dB */
|
||||
0xd9800, /* -8dB */
|
||||
0xde000, /* -7dB */
|
||||
0xe2800, /* -6dB */
|
||||
0xe7e00, /* -5dB */
|
||||
0xec000, /* -4dB */
|
||||
0xf0c00, /* -3dB */
|
||||
0xf5c00, /* -2dB */
|
||||
0xfac00, /* -1dB */
|
||||
0,
|
||||
0x5400, /* 1dB */
|
||||
0xac00, /* 2dB */
|
||||
0x10400, /* 3dB */
|
||||
0x16000, /* 4dB */
|
||||
0x1c000, /* 5dB */
|
||||
0x22400, /* 6dB */
|
||||
0x28400, /* 7dB */
|
||||
0x2ec00, /* 8dB */
|
||||
0x35400, /* 9dB */
|
||||
0x3c000, /* 10dB */
|
||||
0x42c00, /* 11dB */
|
||||
0x49c00, /* 12dB */
|
||||
0x51800, /* 13dB */
|
||||
0x58400, /* 14dB */
|
||||
0x5f800 /* 15dB */
|
||||
};
|
||||
|
||||
static const unsigned int prescale_table[] =
|
||||
{
|
||||
0x80000, /* 0db */
|
||||
0x8e000, /* 1dB */
|
||||
0x9a400, /* 2dB */
|
||||
0xa5800, /* 3dB */
|
||||
0xaf400, /* 4dB */
|
||||
0xb8000, /* 5dB */
|
||||
0xbfc00, /* 6dB */
|
||||
0xc6c00, /* 7dB */
|
||||
0xcd000, /* 8dB */
|
||||
0xd25c0, /* 9dB */
|
||||
0xd7800, /* 10dB */
|
||||
0xdc000, /* 11dB */
|
||||
0xdfc00, /* 12dB */
|
||||
0xe3400, /* 13dB */
|
||||
0xe6800, /* 14dB */
|
||||
0xe9400 /* 15dB */
|
||||
};
|
||||
|
||||
#else /* CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F */
|
||||
|
||||
AUDIOHW_SETTING(VOLUME, "dB", 0, 1,-100, 12, -25)
|
||||
AUDIOHW_SETTING(BASS, "dB", 0, 1, -12, 12, 6)
|
||||
AUDIOHW_SETTING(TREBLE, "dB", 0, 1, -12, 12, 6)
|
||||
AUDIOHW_SETTING(LOUDNESS, "dB", 0, 1, 0, 17, 0)
|
||||
AUDIOHW_SETTING(AVC, "", 0, 1, -1, 4, 0)
|
||||
AUDIOHW_SETTING(MDB_STRENGTH, "dB", 0, 1, 0, 127, 48)
|
||||
AUDIOHW_SETTING(MDB_HARMONICS, "%", 0, 1, 0, 100, 50)
|
||||
AUDIOHW_SETTING(MDB_CENTER, "Hz", 0, 10, 20, 300, 60)
|
||||
AUDIOHW_SETTING(MDB_SHAPE, "Hz", 0, 10, 50, 300, 90)
|
||||
AUDIOHW_SETTING(MDB_ENABLE, "", 0, 1, 0, 1, 0)
|
||||
AUDIOHW_SETTING(SUPERBASS, "", 0, 1, 0, 1, 0)
|
||||
|
||||
#if CONFIG_CODEC == MAS3587F && defined(HAVE_RECORDING)
|
||||
/* MAS3587F and MAS3539F handle clipping prevention internally so we do not
|
||||
* need the prescaler -> CLIPPING_CAP */
|
||||
#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \
|
||||
MONO_VOL_CAP | LIN_GAIN_CAP | MIC_GAIN_CAP)
|
||||
AUDIOHW_SETTING(LEFT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15)
|
||||
AUDIOHW_SETTING(RIGHT_GAIN, "dB", 1, 1, 0, 15, 8, (val - 2) * 15)
|
||||
AUDIOHW_SETTING(MIC_GAIN, "dB", 1, 1, 0, 15, 2, val * 15 + 210)
|
||||
#else
|
||||
/* MAS3587F and MAS3539F handle clipping prevention internally so we do not
|
||||
* need the prescaler -> CLIPPING_CAP */
|
||||
#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | BALANCE_CAP | CLIPPING_CAP | \
|
||||
MONO_VOL_CAP)
|
||||
#endif /* MAS3587F && HAVE_RECORDING */
|
||||
|
||||
/* I2C defines */
|
||||
#define MAS_ADR 0x3c
|
||||
#define MAS_DEV_WRITE (MAS_ADR | 0x00)
|
||||
#define MAS_DEV_READ (MAS_ADR | 0x01)
|
||||
|
||||
/* MAS3587F/MAS3539F registers */
|
||||
#define MAS_DATA_WRITE 0x68
|
||||
#define MAS_DATA_READ 0x69
|
||||
#define MAS_CODEC_WRITE 0x6c
|
||||
#define MAS_CODEC_READ 0x6d
|
||||
#define MAS_CONTROL 0x6a
|
||||
#define MAS_DCCF 0x76
|
||||
#define MAS_DCFR 0x77
|
||||
|
||||
#define MAS_REG_KMDB_SWITCH 0x21
|
||||
#define MAS_REG_KMDB_STR 0x22
|
||||
#define MAS_REG_KMDB_HAR 0x23
|
||||
#define MAS_REG_KMDB_FC 0x24
|
||||
#define MAS_REG_KLOUDNESS 0x1e
|
||||
#define MAS_REG_QPEAK_L 0x0a
|
||||
#define MAS_REG_QPEAK_R 0x0b
|
||||
#define MAS_REG_DQPEAK_L 0x0c
|
||||
#define MAS_REG_DQPEAK_R 0x0d
|
||||
#define MAS_REG_VOLUME_CONTROL 0x10
|
||||
#define MAS_REG_BALANCE 0x11
|
||||
#define MAS_REG_KAVC 0x12
|
||||
#define MAS_REG_KBASS 0x14
|
||||
#define MAS_REG_KTREBLE 0x15
|
||||
|
||||
/* MAS3587F/MAS3539F commands */
|
||||
#define MAS_CMD_READ_ANCILLARY 0x50
|
||||
#define MAS_CMD_FAST_PRG_DL 0x60
|
||||
#define MAS_CMD_READ_IC_VER 0x70
|
||||
#define MAS_CMD_READ_REG 0xa0
|
||||
#define MAS_CMD_WRITE_REG 0xb0
|
||||
#define MAS_CMD_READ_D0_MEM 0xc0
|
||||
#define MAS_CMD_READ_D1_MEM 0xd0
|
||||
#define MAS_CMD_WRITE_D0_MEM 0xe0
|
||||
#define MAS_CMD_WRITE_D1_MEM 0xf0
|
||||
|
||||
/* MAS3587F D0 memory cells */
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
#define MAS_D0_APP_SELECT 0x7f6
|
||||
#define MAS_D0_APP_RUNNING 0x7f7
|
||||
#define MAS_D0_ENCODER_CONTROL 0x7f0
|
||||
#define MAS_D0_IO_CONTROL_MAIN 0x7f1
|
||||
#define MAS_D0_INTERFACE_CONTROL 0x7f2
|
||||
#define MAS_D0_OFREQ_CONTROL 0x7f3
|
||||
#define MAS_D0_OUT_CLK_CONFIG 0x7f4
|
||||
#define MAS_D0_SPD_OUT_BITS 0x7f8
|
||||
#define MAS_D0_SOFT_MUTE 0x7f9
|
||||
#define MAS_D0_OUT_LL 0x7fc
|
||||
#define MAS_D0_OUT_LR 0x7fd
|
||||
#define MAS_D0_OUT_RL 0x7fe
|
||||
#define MAS_D0_OUT_RR 0x7ff
|
||||
#define MAS_D0_MPEG_FRAME_COUNT 0xfd0
|
||||
#define MAS_D0_MPEG_STATUS_1 0xfd1
|
||||
#define MAS_D0_MPEG_STATUS_2 0xfd2
|
||||
#define MAS_D0_CRC_ERROR_COUNT 0xfd3
|
||||
|
||||
/* MAS3539F D0 memory cells */
|
||||
#elif CONFIG_CODEC == MAS3539F
|
||||
#define MAS_D0_APP_SELECT 0x34b
|
||||
#define MAS_D0_APP_RUNNING 0x34c
|
||||
/* no encoder :( */
|
||||
#define MAS_D0_IO_CONTROL_MAIN 0x346
|
||||
#define MAS_D0_INTERFACE_CONTROL 0x347
|
||||
#define MAS_D0_OFREQ_CONTROL 0x348
|
||||
#define MAS_D0_OUT_CLK_CONFIG 0x349
|
||||
#define MAS_D0_SPD_OUT_BITS 0x351
|
||||
#define MAS_D0_SOFT_MUTE 0x350
|
||||
#define MAS_D0_OUT_LL 0x354
|
||||
#define MAS_D0_OUT_LR 0x355
|
||||
#define MAS_D0_OUT_RL 0x356
|
||||
#define MAS_D0_OUT_RR 0x357
|
||||
#define MAS_D0_MPEG_FRAME_COUNT 0xfd0
|
||||
#define MAS_D0_MPEG_STATUS_1 0xfd1
|
||||
#define MAS_D0_MPEG_STATUS_2 0xfd2
|
||||
#define MAS_D0_CRC_ERROR_COUNT 0xfd3
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void audiohw_set_loudness(int value);
|
||||
extern void audiohw_set_avc(int value);
|
||||
extern void audiohw_set_mdb_strength(int value);
|
||||
extern void audiohw_set_mdb_harmonics(int value);
|
||||
extern void audiohw_set_mdb_center(int value);
|
||||
extern void audiohw_set_mdb_shape(int value);
|
||||
extern void audiohw_set_mdb_enable(int value);
|
||||
extern void audiohw_set_superbass(int value);
|
||||
|
||||
#endif /* CONFIG_CODEC */
|
||||
|
||||
#endif /* _MAS35XX_H */
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _MASCODEC_H_
|
||||
#define _MASCODEC_H_
|
||||
|
||||
/* unused: int mas_default_read(unsigned short *buf); */
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
int mas_run(unsigned short address);
|
||||
#endif
|
||||
int mas_readmem(int bank, int addr, unsigned long* dest, int len);
|
||||
int mas_writemem(int bank, int addr, const unsigned long* src, int len);
|
||||
int mas_readreg(int reg);
|
||||
int mas_writereg(int reg, unsigned int val);
|
||||
void mas_reset(void);
|
||||
/* unused: int mas_direct_config_read(unsigned char reg); */
|
||||
int mas_direct_config_write(unsigned char reg, unsigned int val);
|
||||
int mas_codec_writereg(int reg, unsigned int val);
|
||||
int mas_codec_readreg(int reg);
|
||||
unsigned long mas_readver(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_TUNER & S1A0903X01
|
||||
void mas_store_pllfreq(int freq);
|
||||
int mas_get_pllfreq(void);
|
||||
#endif
|
||||
|
||||
|
|
@ -39,15 +39,6 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness,
|
|||
int mdb_center, int mdb_shape, bool mdb_enable,
|
||||
bool superbass);
|
||||
|
||||
/* exported just for mpeg.c, to keep the recording there */
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
void demand_irq_enable(bool on);
|
||||
#endif
|
||||
|
||||
/* new functions, exported to plugin API */
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
void mp3_play_init(void);
|
||||
#endif
|
||||
void mp3_play_data(const void* start, size_t size,
|
||||
mp3_play_callback_t get_more);
|
||||
void mp3_play_pause(bool play);
|
||||
|
|
|
|||
|
|
@ -38,16 +38,6 @@ void rtc_init(void);
|
|||
int rtc_read_datetime(struct tm *tm);
|
||||
int rtc_write_datetime(const struct tm *tm);
|
||||
|
||||
#if CONFIG_RTC == RTC_M41ST84W
|
||||
|
||||
/* The RTC in the Archos devices is used for much more than just the clock
|
||||
data */
|
||||
int rtc_read(unsigned char address);
|
||||
int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes);
|
||||
int rtc_write(unsigned char address, unsigned char value);
|
||||
|
||||
#endif /* RTC_M41ST84W */
|
||||
|
||||
#ifdef HAVE_RTC_ALARM
|
||||
void rtc_set_alarm(int h, int m);
|
||||
void rtc_get_alarm(int *h, int *m);
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
* Tuner header for the Samsung S1A0903X01
|
||||
*
|
||||
* Copyright (C) 2007 Michael Sevakis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _S1A0903X01_H_
|
||||
#define _S1A0903X01_H_
|
||||
|
||||
/* Define additional tuner messages here */
|
||||
#define HAVE_RADIO_MUTE_TIMEOUT
|
||||
|
||||
#if 0
|
||||
#define S1A0903X01_IF_MEASUREMENT (RADIO_SET_CHIP_FIRST+0)
|
||||
#define S1A0903X01_SENSITIVITY (RADIO_SET_CHIP_FIRST+1)
|
||||
#endif
|
||||
|
||||
int s1a0903x01_set(int setting, int value);
|
||||
int s1a0903x01_get(int setting);
|
||||
|
||||
#ifndef CONFIG_TUNER_MULTI
|
||||
#define tuner_get s1a0903x01_get
|
||||
#define tuner_set s1a0903x01_set
|
||||
#endif
|
||||
|
||||
#endif /* _S1A0903X01_H_ */
|
||||
|
|
@ -1,376 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Alan Korr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __SH7034_H__
|
||||
#define __SH7034_H__
|
||||
|
||||
#define GBR 0x00000000
|
||||
|
||||
/* register address macros: */
|
||||
|
||||
#define SMR0_ADDR 0x05FFFEC0
|
||||
#define BRR0_ADDR 0x05FFFEC1
|
||||
#define SCR0_ADDR 0x05FFFEC2
|
||||
#define TDR0_ADDR 0x05FFFEC3
|
||||
#define SSR0_ADDR 0x05FFFEC4
|
||||
#define RDR0_ADDR 0x05FFFEC5
|
||||
#define SMR1_ADDR 0x05FFFEC8
|
||||
#define BRR1_ADDR 0x05FFFEC9
|
||||
#define SCR1_ADDR 0x05FFFECA
|
||||
#define TDR1_ADDR 0x05FFFECB
|
||||
#define SSR1_ADDR 0x05FFFECC
|
||||
#define RDR1_ADDR 0x05FFFECD
|
||||
|
||||
#define ADDRAH_ADDR 0x05FFFEE0
|
||||
#define ADDRAL_ADDR 0x05FFFEE1
|
||||
#define ADDRBH_ADDR 0x05FFFEE2
|
||||
#define ADDRBL_ADDR 0x05FFFEE3
|
||||
#define ADDRCH_ADDR 0x05FFFEE4
|
||||
#define ADDRCL_ADDR 0x05FFFEE5
|
||||
#define ADDRDH_ADDR 0x05FFFEE6
|
||||
#define ADDRDL_ADDR 0x05FFFEE7
|
||||
#define ADCSR_ADDR 0x05FFFEE8
|
||||
#define ADCR_ADDR 0x05FFFEE9
|
||||
|
||||
#define TSTR_ADDR 0x05FFFF00
|
||||
#define TSNC_ADDR 0x05FFFF01
|
||||
#define TMDR_ADDR 0x05FFFF02
|
||||
#define TFCR_ADDR 0x05FFFF03
|
||||
#define TCR0_ADDR 0x05FFFF04
|
||||
#define TIOR0_ADDR 0x05FFFF05
|
||||
#define TIER0_ADDR 0x05FFFF06
|
||||
#define TSR0_ADDR 0x05FFFF07
|
||||
#define TCNT0_ADDR 0x05FFFF08
|
||||
#define GRA0_ADDR 0x05FFFF0A
|
||||
#define GRB0_ADDR 0x05FFFF0C
|
||||
#define TCR1_ADDR 0x05FFFF0E
|
||||
#define TIOR1_ADDR 0x05FFFF0F
|
||||
#define TIER1_ADDR 0x05FFFF10
|
||||
#define TSR1_ADDR 0x05FFFF11
|
||||
#define TCNT1_ADDR 0x05FFFF12
|
||||
#define GRA1_ADDR 0x05FFFF14
|
||||
#define GRB1_ADDR 0x05FFFF16
|
||||
#define TCR2_ADDR 0x05FFFF18
|
||||
#define TIOR2_ADDR 0x05FFFF19
|
||||
#define TIER2_ADDR 0x05FFFF1A
|
||||
#define TSR2_ADDR 0x05FFFF1B
|
||||
#define TCNT2_ADDR 0x05FFFF1C
|
||||
#define GRA2_ADDR 0x05FFFF1E
|
||||
#define GRB2_ADDR 0x05FFFF20
|
||||
#define TCR3_ADDR 0x05FFFF22
|
||||
#define TIOR3_ADDR 0x05FFFF23
|
||||
#define TIER3_ADDR 0x05FFFF24
|
||||
#define TSR3_ADDR 0x05FFFF25
|
||||
#define TCNT3_ADDR 0x05FFFF26
|
||||
#define GRA3_ADDR 0x05FFFF28
|
||||
#define GRB3_ADDR 0x05FFFF2A
|
||||
#define BRA3_ADDR 0x05FFFF2C
|
||||
#define BRB3_ADDR 0x05FFFF2E
|
||||
#define TOCR_ADDR 0x05FFFF31
|
||||
#define TCR4_ADDR 0x05FFFF32
|
||||
#define TIOR4_ADDR 0x05FFFF33
|
||||
#define TIER4_ADDR 0x05FFFF34
|
||||
#define TSR4_ADDR 0x05FFFF35
|
||||
#define TCNT4_ADDR 0x05FFFF36
|
||||
#define GRA4_ADDR 0x05FFFF38
|
||||
#define GRB4_ADDR 0x05FFFF3A
|
||||
#define BRA4_ADDR 0x05FFFF3C
|
||||
#define BRB4_ADDR 0x05FFFF3E
|
||||
|
||||
#define SAR0_ADDR 0x05FFFF40
|
||||
#define DAR0_ADDR 0x05FFFF44
|
||||
#define DMAOR_ADDR 0x05FFFF48
|
||||
#define DTCR0_ADDR 0x05FFFF4A
|
||||
#define CHCR0_ADDR 0x05FFFF4E
|
||||
#define SAR1_ADDR 0x05FFFF50
|
||||
#define DAR1_ADDR 0x05FFFF54
|
||||
#define DTCR1_ADDR 0x05FFFF5A
|
||||
#define CHCR1_ADDR 0x05FFFF5E
|
||||
#define SAR2_ADDR 0x05FFFF60
|
||||
#define DAR2_ADDR 0x05FFFF64
|
||||
#define DTCR2_ADDR 0x05FFFF6A
|
||||
#define CHCR2_ADDR 0x05FFFF6E
|
||||
#define SAR3_ADDR 0x05FFFF70
|
||||
#define DAR3_ADDR 0x05FFFF74
|
||||
#define DTCR3_ADDR 0x05FFFF7A
|
||||
#define CHCR3_ADDR 0x05FFFF7E
|
||||
|
||||
#define IPRA_ADDR 0x05FFFF84
|
||||
#define IPRB_ADDR 0x05FFFF86
|
||||
#define IPRC_ADDR 0x05FFFF88
|
||||
#define IPRD_ADDR 0x05FFFF8A
|
||||
#define IPRE_ADDR 0x05FFFF8C
|
||||
#define ICR_ADDR 0x05FFFF8E
|
||||
|
||||
#define BARH_ADDR 0x05FFFF90
|
||||
#define BARL_ADDR 0x05FFFF92
|
||||
#define BAMRH_ADDR 0x05FFFF94
|
||||
#define BAMRL_ADDR 0x05FFFF96
|
||||
#define BBR_ADDR 0x05FFFF98
|
||||
|
||||
#define BCR_ADDR 0x05FFFFA0
|
||||
#define WCR1_ADDR 0x05FFFFA2
|
||||
#define WCR2_ADDR 0x05FFFFA4
|
||||
#define WCR3_ADDR 0x05FFFFA6
|
||||
#define DCR_ADDR 0x05FFFFA8
|
||||
#define PCR_ADDR 0x05FFFFAA
|
||||
#define RCR_ADDR 0x05FFFFAC
|
||||
#define RTCSR_ADDR 0x05FFFFAE
|
||||
#define RTCNT_ADDR 0x05FFFFB0
|
||||
#define RTCOR_ADDR 0x05FFFFB2
|
||||
|
||||
#define TCSR_ADDR 0x05FFFFB8
|
||||
#define TCNT_ADDR 0x05FFFFB9
|
||||
#define RSTCSR_ADDR 0x05FFFFBB
|
||||
|
||||
#define SBYCR_ADDR 0x05FFFFBC
|
||||
|
||||
#define PADR_ADDR 0x05FFFFC0
|
||||
#define PBDR_ADDR 0x05FFFFC2
|
||||
#define PAIOR_ADDR 0x05FFFFC4
|
||||
#define PBIOR_ADDR 0x05FFFFC6
|
||||
#define PACR1_ADDR 0x05FFFFC8
|
||||
#define PACR2_ADDR 0x05FFFFCA
|
||||
#define PBCR1_ADDR 0x05FFFFCC
|
||||
#define PBCR2_ADDR 0x05FFFFCE
|
||||
#define PCDR_ADDR 0x05FFFFD0
|
||||
|
||||
#define CASCR_ADDR 0x05FFFFEE
|
||||
|
||||
/* byte halves of the ports */
|
||||
#define PADRH_ADDR 0x05FFFFC0
|
||||
#define PADRL_ADDR 0x05FFFFC1
|
||||
#define PBDRH_ADDR 0x05FFFFC2
|
||||
#define PBDRL_ADDR 0x05FFFFC3
|
||||
#define PAIORH_ADDR 0x05FFFFC4
|
||||
#define PAIORL_ADDR 0x05FFFFC5
|
||||
#define PBIORH_ADDR 0x05FFFFC6
|
||||
#define PBIORL_ADDR 0x05FFFFC7
|
||||
|
||||
|
||||
/* A/D control/status register bits */
|
||||
#define ADCSR_CH 0x07 /* Channel/group select */
|
||||
#define ADCSR_CKS 0x08 /* Clock select */
|
||||
#define ADCSR_SCAN 0x10 /* Scan mode */
|
||||
#define ADCSR_ADST 0x20 /* A/D start */
|
||||
#define ADCSR_ADIE 0x40 /* A/D interrupt enable */
|
||||
#define ADCSR_ADF 0x80 /* A/D end flag */
|
||||
|
||||
/* A/D control register bits */
|
||||
#define ADCR_TRGE 0x80 /* Trigger enable */
|
||||
|
||||
/* register macros for direct access: */
|
||||
|
||||
#define SMR0 (*((volatile unsigned char*)SMR0_ADDR))
|
||||
#define BRR0 (*((volatile unsigned char*)BRR0_ADDR))
|
||||
#define SCR0 (*((volatile unsigned char*)SCR0_ADDR))
|
||||
#define TDR0 (*((volatile unsigned char*)TDR0_ADDR))
|
||||
#define SSR0 (*((volatile unsigned char*)SSR0_ADDR))
|
||||
#define RDR0 (*((volatile unsigned char*)RDR0_ADDR))
|
||||
#define SMR1 (*((volatile unsigned char*)SMR1_ADDR))
|
||||
#define BRR1 (*((volatile unsigned char*)BRR1_ADDR))
|
||||
#define SCR1 (*((volatile unsigned char*)SCR1_ADDR))
|
||||
#define TDR1 (*((volatile unsigned char*)TDR1_ADDR))
|
||||
#define SSR1 (*((volatile unsigned char*)SSR1_ADDR))
|
||||
#define RDR1 (*((volatile unsigned char*)RDR1_ADDR))
|
||||
|
||||
#define ADDRA (*((volatile unsigned short*)ADDRAH_ADDR)) /* combined */
|
||||
#define ADDRAH (*((volatile unsigned char*)ADDRAH_ADDR))
|
||||
#define ADDRAL (*((volatile unsigned char*)ADDRAL_ADDR))
|
||||
#define ADDRB (*((volatile unsigned short*)ADDRBH_ADDR)) /* combined */
|
||||
#define ADDRBH (*((volatile unsigned char*)ADDRBH_ADDR))
|
||||
#define ADDRBL (*((volatile unsigned char*)ADDRBL_ADDR))
|
||||
#define ADDRC (*((volatile unsigned short*)ADDRCH_ADDR)) /* combined */
|
||||
#define ADDRCH (*((volatile unsigned char*)ADDRCH_ADDR))
|
||||
#define ADDRCL (*((volatile unsigned char*)ADDRCL_ADDR))
|
||||
#define ADDRD (*((volatile unsigned short*)ADDRDH_ADDR)) /* combined */
|
||||
#define ADDRDH (*((volatile unsigned char*)ADDRDH_ADDR))
|
||||
#define ADDRDL (*((volatile unsigned char*)ADDRDL_ADDR))
|
||||
#define ADCSR (*((volatile unsigned char*)ADCSR_ADDR))
|
||||
#define ADCR (*((volatile unsigned char*)ADCR_ADDR))
|
||||
|
||||
#define TSTR (*((volatile unsigned char*)TSTR_ADDR))
|
||||
#define TSNC (*((volatile unsigned char*)TSNC_ADDR))
|
||||
#define TMDR (*((volatile unsigned char*)TMDR_ADDR))
|
||||
#define TFCR (*((volatile unsigned char*)TFCR_ADDR))
|
||||
#define TCR0 (*((volatile unsigned char*)TCR0_ADDR))
|
||||
#define TIOR0 (*((volatile unsigned char*)TIOR0_ADDR))
|
||||
#define TIER0 (*((volatile unsigned char*)TIER0_ADDR))
|
||||
#define TSR0 (*((volatile unsigned char*)TSR0_ADDR))
|
||||
#define TCNT0 (*((volatile unsigned short*)TCNT0_ADDR))
|
||||
#define GRA0 (*((volatile unsigned short*)GRA0_ADDR))
|
||||
#define GRB0 (*((volatile unsigned short*)GRB0_ADDR))
|
||||
#define TCR1 (*((volatile unsigned char*)TCR1_ADDR))
|
||||
#define TIOR1 (*((volatile unsigned char*)TIOR1_ADDR))
|
||||
#define TIER1 (*((volatile unsigned char*)TIER1_ADDR))
|
||||
#define TSR1 (*((volatile unsigned char*)TSR1_ADDR))
|
||||
#define TCNT1 (*((volatile unsigned short*)TCNT1_ADDR))
|
||||
#define GRA1 (*((volatile unsigned short*)GRA1_ADDR))
|
||||
#define GRB1 (*((volatile unsigned short*)GRB1_ADDR))
|
||||
#define TCR2 (*((volatile unsigned char*)TCR2_ADDR))
|
||||
#define TIOR2 (*((volatile unsigned char*)TIOR2_ADDR))
|
||||
#define TIER2 (*((volatile unsigned char*)TIER2_ADDR))
|
||||
#define TSR2 (*((volatile unsigned char*)TSR2_ADDR))
|
||||
#define TCNT2 (*((volatile unsigned short*)TCNT2_ADDR))
|
||||
#define GRA2 (*((volatile unsigned short*)GRA2_ADDR))
|
||||
#define GRB2 (*((volatile unsigned short*)GRB2_ADDR))
|
||||
#define TCR3 (*((volatile unsigned char*)TCR3_ADDR))
|
||||
#define TIOR3 (*((volatile unsigned char*)TIOR3_ADDR))
|
||||
#define TIER3 (*((volatile unsigned char*)TIER3_ADDR))
|
||||
#define TSR3 (*((volatile unsigned char*)TSR3_ADDR))
|
||||
#define TCNT3 (*((volatile unsigned short*)TCNT3_ADDR))
|
||||
#define GRA3 (*((volatile unsigned short*)GRA3_ADDR))
|
||||
#define GRB3 (*((volatile unsigned short*)GRB3_ADDR))
|
||||
#define BRA3 (*((volatile unsigned short*)BRA3_ADDR))
|
||||
#define BRB3 (*((volatile unsigned short*)BRB3_ADDR))
|
||||
#define TOCR (*((volatile unsigned char*)TOCR_ADDR))
|
||||
#define TCR4 (*((volatile unsigned char*)TCR4_ADDR))
|
||||
#define TIOR4 (*((volatile unsigned char*)TIOR4_ADDR))
|
||||
#define TIER4 (*((volatile unsigned char*)TIER4_ADDR))
|
||||
#define TSR4 (*((volatile unsigned char*)TSR4_ADDR))
|
||||
#define TCNT4 (*((volatile unsigned short*)TCNT4_ADDR))
|
||||
#define GRA4 (*((volatile unsigned short*)GRA4_ADDR))
|
||||
#define GRB4 (*((volatile unsigned short*)GRB4_ADDR))
|
||||
#define BRA4 (*((volatile unsigned short*)BRA4_ADDR))
|
||||
#define BRB4 (*((volatile unsigned short*)BRB4_ADDR))
|
||||
|
||||
#define SAR0 (*((volatile unsigned long*)SAR0_ADDR))
|
||||
#define DAR0 (*((volatile unsigned long*)DAR0_ADDR))
|
||||
#define DMAOR (*((volatile unsigned short*)DMAOR_ADDR))
|
||||
#define DTCR0 (*((volatile unsigned short*)DTCR0_ADDR))
|
||||
#define CHCR0 (*((volatile unsigned short*)CHCR0_ADDR))
|
||||
#define SAR1 (*((volatile unsigned long*)SAR1_ADDR))
|
||||
#define DAR1 (*((volatile unsigned long*)DAR1_ADDR))
|
||||
#define DTCR1 (*((volatile unsigned short*)DTCR1_ADDR))
|
||||
#define CHCR1 (*((volatile unsigned short*)CHCR1_ADDR))
|
||||
#define SAR2 (*((volatile unsigned long*)SAR2_ADDR))
|
||||
#define DAR2 (*((volatile unsigned long*)DAR2_ADDR))
|
||||
#define DTCR2 (*((volatile unsigned short*)DTCR2_ADDR))
|
||||
#define CHCR2 (*((volatile unsigned short*)CHCR2_ADDR))
|
||||
#define SAR3 (*((volatile unsigned long*)SAR3_ADDR))
|
||||
#define DAR3 (*((volatile unsigned long*)DAR3_ADDR))
|
||||
#define DTCR3 (*((volatile unsigned short*)DTCR3_ADDR))
|
||||
#define CHCR3 (*((volatile unsigned short*)CHCR3_ADDR))
|
||||
|
||||
#define IPRA (*((volatile unsigned short*)IPRA_ADDR))
|
||||
#define IPRB (*((volatile unsigned short*)IPRB_ADDR))
|
||||
#define IPRC (*((volatile unsigned short*)IPRC_ADDR))
|
||||
#define IPRD (*((volatile unsigned short*)IPRD_ADDR))
|
||||
#define IPRE (*((volatile unsigned short*)IPRE_ADDR))
|
||||
#define ICR (*((volatile unsigned short*)ICR_ADDR))
|
||||
|
||||
#define BAR (*((volatile unsigned long*)BARH_ADDR)) /* combined */
|
||||
#define BARH (*((volatile unsigned short*)BARH_ADDR))
|
||||
#define BARL (*((volatile unsigned short*)BARL_ADDR))
|
||||
#define BAMR (*((volatile unsigned long*)BAMRH_ADDR)) /* combined */
|
||||
#define BAMRH (*((volatile unsigned short*)BAMRH_ADDR))
|
||||
#define BAMRL (*((volatile unsigned short*)BAMRL_ADDR))
|
||||
#define BBR (*((volatile unsigned short*)BBR_ADDR))
|
||||
|
||||
#define BCR (*((volatile unsigned short*)BCR_ADDR))
|
||||
#define WCR1 (*((volatile unsigned short*)WCR1_ADDR))
|
||||
#define WCR2 (*((volatile unsigned short*)WCR2_ADDR))
|
||||
#define WCR3 (*((volatile unsigned short*)WCR3_ADDR))
|
||||
#define DCR (*((volatile unsigned short*)DCR_ADDR))
|
||||
#define PCR (*((volatile unsigned short*)PCR_ADDR))
|
||||
#define RCR (*((volatile unsigned short*)RCR_ADDR))
|
||||
#define RTCSR (*((volatile unsigned short*)RTCSR_ADDR))
|
||||
#define RTCNT (*((volatile unsigned short*)RTCNT_ADDR))
|
||||
#define RTCOR (*((volatile unsigned short*)RTCOR_ADDR))
|
||||
|
||||
#define TCSR_R (*((volatile unsigned char*)TCSR_ADDR))
|
||||
#define TCSR_W (*((volatile unsigned short*)(TCSR_ADDR & ~1)))
|
||||
#define TCNT_R (*((volatile unsigned char*)TCNT_ADDR))
|
||||
#define TCNT_W (*((volatile unsigned short*)(TCNT_ADDR & ~1)))
|
||||
#define RSTCSR_R (*((volatile unsigned char*)RSTCSR_ADDR))
|
||||
#define RSTCSR_W (*((volatile unsigned short*)(RSTCSR_ADDR & ~1)))
|
||||
|
||||
#define SBYCR (*((volatile unsigned char*)SBYCR_ADDR))
|
||||
|
||||
#define PADR (*((volatile unsigned short*)PADR_ADDR))
|
||||
#define PBDR (*((volatile unsigned short*)PBDR_ADDR))
|
||||
#define PAIOR (*((volatile unsigned short*)PAIOR_ADDR))
|
||||
#define PBIOR (*((volatile unsigned short*)PBIOR_ADDR))
|
||||
#define PACR1 (*((volatile unsigned short*)PACR1_ADDR))
|
||||
#define PACR2 (*((volatile unsigned short*)PACR2_ADDR))
|
||||
#define PBCR1 (*((volatile unsigned short*)PBCR1_ADDR))
|
||||
#define PBCR2 (*((volatile unsigned short*)PBCR2_ADDR))
|
||||
#define PCDR (*((volatile unsigned short*)PCDR_ADDR))
|
||||
|
||||
#define CASCR (*((volatile unsigned char*)CASCR_ADDR))
|
||||
|
||||
/* byte halves of the ports */
|
||||
#define PADRH (*((volatile unsigned char*)PADRH_ADDR))
|
||||
#define PADRL (*((volatile unsigned char*)PADRL_ADDR))
|
||||
#define PBDRH (*((volatile unsigned char*)PBDRH_ADDR))
|
||||
#define PBDRL (*((volatile unsigned char*)PBDRL_ADDR))
|
||||
#define PAIORH (*((volatile unsigned char*)PAIORH_ADDR))
|
||||
#define PAIORL (*((volatile unsigned char*)PAIORL_ADDR))
|
||||
#define PBIORH (*((volatile unsigned char*)PBIORH_ADDR))
|
||||
#define PBIORL (*((volatile unsigned char*)PBIORL_ADDR))
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Register bit definitions
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Serial mode register bits
|
||||
*/
|
||||
|
||||
#define SYNC_MODE 0x80
|
||||
#define SEVEN_BIT_DATA 0x40
|
||||
#define PARITY_ON 0x20
|
||||
#define ODD_PARITY 0x10
|
||||
#define STOP_BITS_2 0x08
|
||||
#define ENABLE_MULTIP 0x04
|
||||
#define PHI_64 0x03
|
||||
#define PHI_16 0x02
|
||||
#define PHI_4 0x01
|
||||
|
||||
/*
|
||||
* Serial control register bits
|
||||
*/
|
||||
#define SCI_TIE 0x80 /* Transmit interrupt enable */
|
||||
#define SCI_RIE 0x40 /* Receive interrupt enable */
|
||||
#define SCI_TE 0x20 /* Transmit enable */
|
||||
#define SCI_RE 0x10 /* Receive enable */
|
||||
#define SCI_MPIE 0x08 /* Multiprocessor interrupt enable */
|
||||
#define SCI_TEIE 0x04 /* Transmit end interrupt enable */
|
||||
#define SCI_CKE1 0x02 /* Clock enable 1 */
|
||||
#define SCI_CKE0 0x01 /* Clock enable 0 */
|
||||
|
||||
/*
|
||||
* Serial status register bits
|
||||
*/
|
||||
#define SCI_TDRE 0x80 /* Transmit data register empty */
|
||||
#define SCI_RDRF 0x40 /* Receive data register full */
|
||||
#define SCI_ORER 0x20 /* Overrun error */
|
||||
#define SCI_FER 0x10 /* Framing error */
|
||||
#define SCI_PER 0x08 /* Parity error */
|
||||
#define SCI_TEND 0x04 /* Transmit end */
|
||||
#define SCI_MPB 0x02 /* Multiprocessor bit */
|
||||
#define SCI_MPBT 0x01 /* Multiprocessor bit transfer */
|
||||
|
||||
/* Timer frequency */
|
||||
#define TIMER_FREQ CPU_FREQ
|
||||
|
||||
#endif
|
||||
|
|
@ -109,17 +109,6 @@ void sound_set_hw_eq_band5_frequency(int value);
|
|||
#endif /* AUDIOHW_HAVE_EQ_BAND5 */
|
||||
#endif /* AUDIOHW_HAVE_EQ */
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
void sound_set_loudness(int value);
|
||||
void sound_set_avc(int value);
|
||||
void sound_set_mdb_strength(int value);
|
||||
void sound_set_mdb_harmonics(int value);
|
||||
void sound_set_mdb_center(int value);
|
||||
void sound_set_mdb_shape(int value);
|
||||
void sound_set_mdb_enable(int value);
|
||||
void sound_set_superbass(int value);
|
||||
#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
|
||||
void sound_set(int setting, int value);
|
||||
int sound_val2phys(int setting, int value);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@
|
|||
#ifndef __TUNER_H__
|
||||
#define __TUNER_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "hwcompat.h"
|
||||
|
||||
#ifdef HAVE_RDS_CAP
|
||||
#include <sys/types.h>
|
||||
|
|
@ -114,12 +115,6 @@ extern int (*tuner_get)(int setting);
|
|||
#include "lv24020lp.h"
|
||||
#endif
|
||||
|
||||
/** Samsung S1A0903X01 **/
|
||||
#if (CONFIG_TUNER & S1A0903X01)
|
||||
/* Ondio FM, FM Recorder */
|
||||
#include "s1a0903x01.h"
|
||||
#endif
|
||||
|
||||
/** Philips TEA5760 **/
|
||||
#if (CONFIG_TUNER & TEA5760)
|
||||
#include "tea5760.h"
|
||||
|
|
|
|||
|
|
@ -134,14 +134,8 @@ enum
|
|||
};
|
||||
|
||||
#ifdef HAVE_USB_POWER
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define USBPOWER_BUTTON BUTTON_F1
|
||||
#define USBPOWER_BTN_IGNORE BUTTON_ON
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
#define USBPOWER_BUTTON BUTTON_MENU
|
||||
#define USBPOWER_BTN_IGNORE BUTTON_OFF
|
||||
/*allow people to define this in config-target.h if they need it*/
|
||||
#elif !defined(USBPOWER_BTN_IGNORE)
|
||||
#if !defined(USBPOWER_BTN_IGNORE)
|
||||
#define USBPOWER_BTN_IGNORE 0
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ include $(FIRMDIR)/asm/asm.make
|
|||
|
||||
FIRMLIB_SRC += $(call preprocess, $(FIRMDIR)/SOURCES)
|
||||
FIRMLIB_OBJ := $(call c2obj, $(FIRMLIB_SRC))
|
||||
ifeq (,$(findstring -DARCHOS_PLAYER,$(TARGET)))
|
||||
FIRMLIB_OBJ += $(BUILDDIR)/sysfont.o
|
||||
endif
|
||||
FIRMLIB_OBJ += $(BUILDDIR)/sysfont.o
|
||||
OTHER_SRC += $(FIRMLIB_SRC)
|
||||
|
||||
FIRMLIB = $(BUILDDIR)/firmware/libfirmware.a
|
||||
|
|
|
|||
113
firmware/rolo.c
113
firmware/rolo.c
|
|
@ -123,10 +123,7 @@ static void rolo_error(const char *text)
|
|||
lcd_scroll_stop();
|
||||
}
|
||||
|
||||
#if CONFIG_CPU == SH7034 || CONFIG_CPU == IMX31L || CONFIG_CPU == RK27XX
|
||||
/* these are in assembler file "descramble.S" for SH7034 */
|
||||
extern unsigned short descramble(const unsigned char* source,
|
||||
unsigned char* dest, int length);
|
||||
#if CONFIG_CPU == IMX31L || CONFIG_CPU == RK27XX
|
||||
/* this is in firmware/target/arm/imx31/rolo_restart.c for IMX31 */
|
||||
/* this is in firmware/target/arm/rk27xx/rolo_restart.c for rk27xx */
|
||||
extern void rolo_restart(const unsigned char* source, unsigned char* dest,
|
||||
|
|
@ -299,113 +296,7 @@ int rolo_load(const char* filename)
|
|||
/* never reached */
|
||||
return 0;
|
||||
}
|
||||
#else /* defined(CPU_SH) */
|
||||
int rolo_load(const char* filename)
|
||||
{
|
||||
int fd;
|
||||
long length;
|
||||
long file_length;
|
||||
unsigned short checksum,file_checksum;
|
||||
unsigned char* ramstart = (void*)&loadaddress;
|
||||
unsigned char* filebuf;
|
||||
size_t filebuf_size;
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_puts(0, 0, "ROLO...");
|
||||
lcd_puts(0, 1, "Loading");
|
||||
lcd_update();
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
lcd_remote_clear_display();
|
||||
lcd_remote_puts(0, 0, "ROLO...");
|
||||
lcd_remote_puts(0, 1, "Loading");
|
||||
lcd_remote_update();
|
||||
#endif
|
||||
|
||||
audio_stop();
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if(-1 == fd) {
|
||||
rolo_error("File not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA;
|
||||
|
||||
/* get the system buffer. release only in case of error, otherwise
|
||||
* we don't return anyway */
|
||||
rolo_handle = core_alloc_maximum("rolo", &filebuf_size, NULL);
|
||||
filebuf = core_get_data(rolo_handle);
|
||||
|
||||
/* Read file length from header and compare to real file length */
|
||||
lseek(fd, FIRMWARE_OFFSET_FILE_LENGTH, SEEK_SET);
|
||||
if(read(fd, &file_length, 4) != 4) {
|
||||
rolo_error("Error Reading File Length");
|
||||
return -1;
|
||||
}
|
||||
if (length != file_length) {
|
||||
rolo_error("File length mismatch");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read and save checksum */
|
||||
lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
|
||||
if (read(fd, &file_checksum, 2) != 2) {
|
||||
rolo_error("Error Reading checksum");
|
||||
return -1;
|
||||
}
|
||||
lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
|
||||
|
||||
/* verify that file can be read and descrambled */
|
||||
if ((size_t)((2*length)+4) >= filebuf_size) {
|
||||
rolo_error("Not enough room to load file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read(fd, &filebuf[length], length) != (int)length) {
|
||||
rolo_error("Error Reading File");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lcd_puts(0, 1, "Descramble");
|
||||
lcd_update();
|
||||
|
||||
checksum = descramble(filebuf + length, filebuf, length);
|
||||
|
||||
/* Verify checksum against file header */
|
||||
if (checksum != file_checksum) {
|
||||
rolo_error("Checksum Error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STORAGE_FLUSH
|
||||
lcd_puts(0, 1, "Flushing ");
|
||||
lcd_update();
|
||||
storage_flush();
|
||||
#endif
|
||||
|
||||
lcd_puts(0, 1, "Executing ");
|
||||
lcd_update();
|
||||
|
||||
set_irq_level(HIGHEST_IRQ_LEVEL);
|
||||
|
||||
/* Calling these 2 initialization routines was necessary to get the
|
||||
the origional Archos version of the firmware to load and execute. */
|
||||
system_init(); /* Initialize system for restart */
|
||||
i2c_init(); /* Init i2c bus - it seems like a good idea */
|
||||
ICR = IRQ0_EDGE_TRIGGER; /* Make IRQ0 edge triggered */
|
||||
TSTR = 0xE0; /* disable all timers */
|
||||
/* model-specific de-init, needed when flashed */
|
||||
/* Especially the Archos software is picky about this */
|
||||
#if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \
|
||||
defined(ARCHOS_FMRECORDER)
|
||||
PAIOR = 0x0FA0;
|
||||
#endif
|
||||
rolo_restart(filebuf, ramstart, length);
|
||||
|
||||
return 0; /* this is never reached */
|
||||
(void)checksum; (void)file_checksum;
|
||||
}
|
||||
#endif /* */
|
||||
#endif /* CPU_COLDFIRE | CPU_ARM | CPU_MIPS */
|
||||
#else /* !defined(IRIVER_IFP7XX_SERIES) */
|
||||
int rolo_load(const char* filename)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ STARTUP(target/arm/pp/crt0-pp.o)
|
|||
#elif defined(CPU_ARM)
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
STARTUP(target/arm/crt0.o)
|
||||
#elif CONFIG_CPU == SH7034
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
STARTUP(target/sh/crt0.o)
|
||||
#else
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
STARTUP(crt0.o)
|
||||
|
|
|
|||
|
|
@ -128,16 +128,6 @@ int sound_current(int setting)
|
|||
SOUND_CUR_SET(BALANCE, global_settings.balance)
|
||||
SOUND_CUR_SET(CHANNELS, global_settings.channel_config)
|
||||
SOUND_CUR_SET(STEREO_WIDTH, global_settings.stereo_width)
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
SOUND_CUR_SET(LOUDNESS, global_settings.loudness)
|
||||
SOUND_CUR_SET(AVC, global_settings.avc)
|
||||
SOUND_CUR_SET(MDB_STRENGTH, global_settings.mdb_strength)
|
||||
SOUND_CUR_SET(MDB_HARMONICS, global_settings.mdb_harmonics)
|
||||
SOUND_CUR_SET(MDB_CENTER, global_settings.mdb_center)
|
||||
SOUND_CUR_SET(MDB_SHAPE, global_settings.mdb_shape)
|
||||
SOUND_CUR_SET(MDB_ENABLE, global_settings.mdb_enable)
|
||||
SOUND_CUR_SET(SUPERBASS, global_settings.superbass)
|
||||
#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
|
||||
SOUND_CUR_SET(BASS_CUTOFF, global_settings.bass_cutoff)
|
||||
#endif
|
||||
|
|
@ -626,72 +616,6 @@ void sound_set_hw_eq_band4_width(int value)
|
|||
#endif
|
||||
#endif /* AUDIOHW_HAVE_EQ */
|
||||
|
||||
#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F
|
||||
void sound_set_loudness(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_loudness(value);
|
||||
}
|
||||
|
||||
void sound_set_avc(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_avc(value);
|
||||
}
|
||||
|
||||
void sound_set_mdb_strength(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_mdb_strength(value);
|
||||
}
|
||||
|
||||
void sound_set_mdb_harmonics(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_mdb_harmonics(value);
|
||||
}
|
||||
|
||||
void sound_set_mdb_center(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_mdb_center(value);
|
||||
}
|
||||
|
||||
void sound_set_mdb_shape(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_mdb_shape(value);
|
||||
}
|
||||
|
||||
void sound_set_mdb_enable(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_mdb_enable(value);
|
||||
}
|
||||
|
||||
void sound_set_superbass(int value)
|
||||
{
|
||||
if (!audio_is_initialized)
|
||||
return;
|
||||
|
||||
audiohw_set_superbass(value);
|
||||
}
|
||||
#endif /* CONFIG_CODEC == MAS3587F || CONFIG_CODEC == MAS3539F */
|
||||
|
||||
#if defined(HAVE_PITCHCONTROL)
|
||||
void sound_set_pitch(int32_t pitch)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,35 +28,7 @@
|
|||
|
||||
/* colour definitions are R, G, B */
|
||||
|
||||
#if defined(ARCHOS_RECORDER)
|
||||
#define UI_TITLE "Jukebox Recorder"
|
||||
#define UI_WIDTH 270 /* width of GUI window */
|
||||
#define UI_HEIGHT 406 /* height of GUI window */
|
||||
#define UI_LCD_POSX 80 /* x position of lcd */
|
||||
#define UI_LCD_POSY 104 /* y position of lcd */
|
||||
|
||||
#elif defined(ARCHOS_PLAYER)
|
||||
#define UI_TITLE "Jukebox Player"
|
||||
#define UI_WIDTH 284 /* width of GUI window */
|
||||
#define UI_HEIGHT 420 /* height of GUI window */
|
||||
#define UI_LCD_POSX 75 /* x position of lcd */
|
||||
#define UI_LCD_POSY 116 /* y position of lcd */
|
||||
|
||||
#elif defined(ARCHOS_FMRECORDER) || defined(ARCHOS_RECORDERV2)
|
||||
#define UI_TITLE "Jukebox FM Recorder"
|
||||
#define UI_WIDTH 285 /* width of GUI window */
|
||||
#define UI_HEIGHT 414 /* height of GUI window */
|
||||
#define UI_LCD_POSX 87 /* x position of lcd */
|
||||
#define UI_LCD_POSY 77 /* y position of lcd */
|
||||
|
||||
#elif defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM)
|
||||
#define UI_TITLE "Ondio"
|
||||
#define UI_WIDTH 155 /* width of GUI window */
|
||||
#define UI_HEIGHT 334 /* height of GUI window */
|
||||
#define UI_LCD_POSX 21 /* x position of lcd */
|
||||
#define UI_LCD_POSY 82 /* y position of lcd */
|
||||
|
||||
#elif defined(IRIVER_H120) || defined(IRIVER_H100)
|
||||
#if defined(IRIVER_H120) || defined(IRIVER_H100)
|
||||
#define UI_TITLE "iriver H1x0"
|
||||
#define UI_WIDTH 379 /* width of GUI window */
|
||||
#define UI_HEIGHT 508 /* height of GUI window */
|
||||
|
|
@ -238,14 +210,6 @@
|
|||
#define UI_LCD_POSX 115 /* x position of lcd */
|
||||
#define UI_LCD_POSY 54 /* y position of lcd */
|
||||
|
||||
#elif defined(ARCHOS_AV300)
|
||||
#define UI_TITLE "Archos AV300"
|
||||
/* We are temporarily using a 2bpp LCD driver and dummy bitmap */
|
||||
#define UI_WIDTH 420 /* width of GUI window */
|
||||
#define UI_HEIGHT 340 /* height of GUI window */
|
||||
#define UI_LCD_POSX 50 /* x position of lcd */
|
||||
#define UI_LCD_POSY 50 /* y position of lcd */
|
||||
|
||||
#elif defined(MROBE_100)
|
||||
#define UI_TITLE "Olympus M:Robe 100"
|
||||
#define UI_WIDTH 247 /* width of GUI window */
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "string.h"
|
||||
#include "adc.h"
|
||||
|
||||
/**************************************************************************
|
||||
** The A/D conversion is done every tick, in three steps:
|
||||
**
|
||||
** 1) On the tick interrupt, the conversion of channels 0-3 is started, and
|
||||
** the A/D interrupt is enabled.
|
||||
**
|
||||
** 2) After the conversion is done (approx. 256*4 cycles later), an interrupt
|
||||
** is generated at level 1, which is the same level as the tick interrupt
|
||||
** itself. This interrupt will be pending until the tick interrupt is
|
||||
** finished.
|
||||
** When the A/D interrupt is finally served, it will read the results
|
||||
** from the first conversion and start the conversion of channels 4-7.
|
||||
**
|
||||
** 3) When the conversion of channels 4-7 is finished, the interrupt is
|
||||
** triggered again, and the results are read. This time, no new
|
||||
** conversion is started, it will be done in the next tick interrupt.
|
||||
**
|
||||
** Thus, each channel will be updated HZ times per second.
|
||||
**
|
||||
*************************************************************************/
|
||||
|
||||
static int current_channel;
|
||||
static unsigned short adcdata[NUM_ADC_CHANNELS];
|
||||
|
||||
static void adc_tick(void)
|
||||
{
|
||||
/* Start a conversion of channel group 0. This will trigger an interrupt,
|
||||
and the interrupt handler will take care of group 1. */
|
||||
|
||||
current_channel = 0;
|
||||
ADCSR = ADCSR_ADST | ADCSR_ADIE | ADCSR_SCAN | 3;
|
||||
}
|
||||
|
||||
void ADITI(void) __attribute__((interrupt_handler));
|
||||
void ADITI(void)
|
||||
{
|
||||
if(ADCSR & ADCSR_ADF)
|
||||
{
|
||||
ADCSR = 0;
|
||||
|
||||
if(current_channel == 0)
|
||||
{
|
||||
adcdata[0] = ADDRA >> 6;
|
||||
adcdata[1] = ADDRB >> 6;
|
||||
adcdata[2] = ADDRC >> 6;
|
||||
adcdata[3] = ADDRD >> 6;
|
||||
current_channel = 4;
|
||||
|
||||
/* Convert the next group */
|
||||
ADCSR = ADCSR_ADST | ADCSR_ADIE | ADCSR_SCAN | 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
adcdata[4] = ADDRA >> 6;
|
||||
adcdata[5] = ADDRB >> 6;
|
||||
adcdata[6] = ADDRC >> 6;
|
||||
adcdata[7] = ADDRD >> 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short adc_read(int channel)
|
||||
{
|
||||
return adcdata[channel];
|
||||
}
|
||||
|
||||
void adc_init(void)
|
||||
{
|
||||
ADCR = 0x7f; /* No external trigger; other bits should be 1 according
|
||||
to the manual... */
|
||||
|
||||
ADCSR = 0;
|
||||
|
||||
current_channel = 0;
|
||||
|
||||
/* Enable the A/D IRQ on level 1 */
|
||||
IPRE = (IPRE & 0xf0ff) | 0x0100;
|
||||
|
||||
tick_add_task(adc_tick);
|
||||
|
||||
sleep(2); /* Ensure valid readings when adc_init returns */
|
||||
}
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
#include "config.h"
|
||||
|
||||
ENTRY(start)
|
||||
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
STARTUP(target/sh/crt0.o)
|
||||
|
||||
#define PLUGINSIZE PLUGIN_BUFFER_SIZE
|
||||
#define CODECSIZE CODEC_SIZE
|
||||
|
||||
#ifdef DEBUG
|
||||
#define STUBOFFSET 0x10000
|
||||
#else
|
||||
#define STUBOFFSET 0
|
||||
#endif
|
||||
|
||||
#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE
|
||||
|
||||
#define DRAMORIG 0x09000000 + STUBOFFSET
|
||||
#define IRAMORIG 0x0f000000
|
||||
#define IRAMSIZE 0x1000
|
||||
|
||||
/* End of the audio buffer, where the codec buffer starts */
|
||||
#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE)
|
||||
|
||||
/* Where the codec buffer ends, and the plugin buffer starts */
|
||||
#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
|
||||
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vectors :
|
||||
{
|
||||
loadaddress = .;
|
||||
_loadaddress = .;
|
||||
KEEP(*(.resetvectors));
|
||||
*(.resetvectors);
|
||||
KEEP(*(.vectors));
|
||||
*(.vectors);
|
||||
} > DRAM
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(0x200);
|
||||
*(.init.text)
|
||||
*(.text*)
|
||||
. = ALIGN(0x4);
|
||||
} > DRAM
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata) /* problems without this, dunno why */
|
||||
*(.rodata*)
|
||||
*(.rodata.str1.1)
|
||||
*(.rodata.str1.4)
|
||||
. = ALIGN(0x4);
|
||||
|
||||
/* Pseudo-allocate the copies of the data sections */
|
||||
_datacopy = .;
|
||||
} > DRAM
|
||||
|
||||
/* TRICK ALERT! For RAM execution, we put the .data section at the
|
||||
same load address as the copy. Thus, we don't waste extra RAM
|
||||
when we don't actually need the copy. */
|
||||
.data : AT ( _datacopy )
|
||||
{
|
||||
_datastart = .;
|
||||
*(.data*)
|
||||
. = ALIGN(0x4);
|
||||
_dataend = .;
|
||||
} > DRAM
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.eh_frame)
|
||||
}
|
||||
|
||||
.iram IRAMORIG :
|
||||
{
|
||||
_iramstart = .;
|
||||
*(.icode)
|
||||
*(.irodata)
|
||||
*(.idata)
|
||||
_iramend = .;
|
||||
} > IRAM AT> DRAM
|
||||
|
||||
_iramcopy = LOADADDR(.iram);
|
||||
_noloaddram = LOADADDR(.iram);
|
||||
|
||||
.ibss (NOLOAD) :
|
||||
{
|
||||
_iedata = .;
|
||||
*(.ibss)
|
||||
. = ALIGN(0x4);
|
||||
_iend = .;
|
||||
} > IRAM
|
||||
|
||||
.stack _noloaddram (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
_stackbegin = .;
|
||||
. += 0x2000;
|
||||
_stackend = .;
|
||||
} > DRAM
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_edata = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(0x4);
|
||||
_end = .;
|
||||
} > DRAM
|
||||
|
||||
.audiobuf (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_audiobuffer = .;
|
||||
audiobuffer = .;
|
||||
} > DRAM
|
||||
|
||||
.audiobufend ENDAUDIOADDR (NOLOAD) :
|
||||
{
|
||||
audiobufend = .;
|
||||
_audiobufend = .;
|
||||
} > DRAM
|
||||
|
||||
.codec ENDAUDIOADDR (NOLOAD) :
|
||||
{
|
||||
codecbuf = .;
|
||||
_codecbuf = .;
|
||||
}
|
||||
|
||||
.plugin ENDADDR (NOLOAD) :
|
||||
{
|
||||
_pluginbuf = .;
|
||||
pluginbuf = .;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include <stdbool.h>
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "ata-driver.h"
|
||||
#include "hwcompat.h"
|
||||
|
||||
#define ATA_CONTROL1 ((volatile unsigned char*)0x06200206)
|
||||
#define ATA_CONTROL2 ((volatile unsigned char*)0x06200306)
|
||||
|
||||
volatile unsigned char* ata_control;
|
||||
|
||||
void ata_reset(void)
|
||||
{
|
||||
/* state HRR0 */
|
||||
and_b(~0x02, &PADRH); /* assert _RESET */
|
||||
sleep(1); /* > 25us */
|
||||
|
||||
/* state HRR1 */
|
||||
or_b(0x02, &PADRH); /* negate _RESET */
|
||||
sleep(1); /* > 2ms */
|
||||
}
|
||||
|
||||
void ata_enable(bool on)
|
||||
{
|
||||
if(on)
|
||||
and_b(~0x80, &PADRL); /* enable ATA */
|
||||
else
|
||||
or_b(0x80, &PADRL); /* disable ATA */
|
||||
|
||||
or_b(0x80, &PAIORL);
|
||||
}
|
||||
|
||||
void ata_device_init(void)
|
||||
{
|
||||
or_b(0x02, &PAIORH); /* output for ATA reset */
|
||||
or_b(0x02, &PADRH); /* release ATA reset */
|
||||
PACR2 &= 0xBFFF; /* GPIO function for PA7 (IDE enable) */
|
||||
|
||||
if (HW_MASK & ATA_ADDRESS_200)
|
||||
ata_control = ATA_CONTROL1;
|
||||
else
|
||||
ata_control = ATA_CONTROL2;
|
||||
}
|
||||
|
||||
bool ata_is_coldstart(void)
|
||||
{
|
||||
return (PACR2 & 0x4000) != 0;
|
||||
}
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _copy_read_sectors
|
||||
.type _copy_read_sectors,@function
|
||||
|
||||
/* Read a number of words from the ATA data port
|
||||
*
|
||||
* Assumes wordcount to be a multiple of 4
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - buffer address
|
||||
* r5 - word count
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1/r2 - read buffers
|
||||
* r3 - mask (if unaligned)
|
||||
* r4 - current address
|
||||
* r5 - end address
|
||||
* r6 - ata port
|
||||
*/
|
||||
|
||||
_copy_read_sectors:
|
||||
add r5, r5 /* words -> bytes */
|
||||
add r4, r5 /* bytes -> end address */
|
||||
add #-12, r5 /* adjust for offsets */
|
||||
mov.l .ata_data, r6
|
||||
|
||||
mov r4, r0
|
||||
tst #1, r0 /* 16-bit aligned ? */
|
||||
bt .r_aligned /* yes, do word copy */
|
||||
|
||||
/* not 16-bit aligned */
|
||||
mov #-1, r3 /* prepare a bit mask for high byte */
|
||||
shll8 r3 /* r3 = 0xFFFFFF00 */
|
||||
|
||||
mov.w @r6, r2 /* read first word (1st round) */
|
||||
mov.b r2, @r4 /* store low byte of first word */
|
||||
bra .r_start_b /* jump into loop after next instr. */
|
||||
add #-5, r4 /* adjust for dest. offsets; now even */
|
||||
|
||||
.align 2
|
||||
.r_loop_b: /* main loop: copy 4 words in a row */
|
||||
mov.w @r6, r2 /* read first word (2+ round) */
|
||||
and r3, r1 /* get high byte of fourth word (2+ round) */
|
||||
extu.b r2, r0 /* get low byte of first word (2+ round) */
|
||||
or r1, r0 /* combine with high byte of fourth word */
|
||||
mov.w r0, @(4, r4) /* store at buf[4] */
|
||||
nop /* maintain alignment */
|
||||
.r_start_b:
|
||||
mov.w @r6, r1 /* read second word */
|
||||
and r3, r2 /* get high byte of first word */
|
||||
extu.b r1, r0 /* get low byte of second word */
|
||||
or r2, r0 /* combine with high byte of first word */
|
||||
mov.w r0, @(6, r4) /* store at buf[6] */
|
||||
add #8, r4 /* buf += 8 */
|
||||
mov.w @r6, r2 /* read third word */
|
||||
and r3, r1 /* get high byte of second word */
|
||||
extu.b r2, r0 /* get low byte of third word */
|
||||
or r1, r0 /* combine with high byte of second word */
|
||||
mov.w r0, @r4 /* store at buf[0] */
|
||||
cmp/hi r4, r5 /* check for end */
|
||||
mov.w @r6, r1 /* read fourth word */
|
||||
and r3, r2 /* get high byte of third word */
|
||||
extu.b r1, r0 /* get low byte of fourth word */
|
||||
or r2, r0 /* combine with high byte of third word */
|
||||
mov.w r0, @(2, r4) /* store at buf[2] */
|
||||
bt .r_loop_b
|
||||
/* 24 instructions for 4 copies, takes 30 clock cycles (4 wait) */
|
||||
/* avg. 7.5 cycles per word */
|
||||
|
||||
swap.b r1, r0 /* get high byte of last word */
|
||||
rts
|
||||
mov.b r0, @(4, r4) /* and store it */
|
||||
|
||||
/* 16-bit aligned, loop(read and store word) */
|
||||
.r_aligned:
|
||||
mov.w @r6, r2 /* read first word (1st round) */
|
||||
bra .r_start_w /* jump into loop after next instr. */
|
||||
add #-6, r4 /* adjust for destination offsets */
|
||||
|
||||
.align 2
|
||||
.r_loop_w: /* main loop: copy 4 words in a row */
|
||||
mov.w @r6, r2 /* read first word (2+ round) */
|
||||
swap.b r1, r0 /* swap fourth word (2+ round) */
|
||||
mov.w r0, @(4, r4) /* store fourth word (2+ round) */
|
||||
nop /* maintain alignment */
|
||||
.r_start_w:
|
||||
mov.w @r6, r1 /* read second word */
|
||||
swap.b r2, r0 /* swap first word */
|
||||
mov.w r0, @(6, r4) /* store first word in buf[6] */
|
||||
add #8, r4 /* buf += 8 */
|
||||
mov.w @r6, r2 /* read third word */
|
||||
swap.b r1, r0 /* swap second word */
|
||||
mov.w r0, @r4 /* store second word in buf[0] */
|
||||
cmp/hi r4, r5 /* check for end */
|
||||
mov.w @r6, r1 /* read fourth word */
|
||||
swap.b r2, r0 /* swap third word */
|
||||
mov.w r0, @(2, r4) /* store third word */
|
||||
bt .r_loop_w
|
||||
/* 16 instructions for 4 copies, takes 22 clock cycles (4 wait) */
|
||||
/* avg. 5.5 cycles per word */
|
||||
|
||||
swap.b r1, r0 /* swap fourth word (last round) */
|
||||
rts
|
||||
mov.w r0, @(4, r4) /* and store it */
|
||||
|
||||
.r_end:
|
||||
.size _copy_read_sectors,.r_end-_copy_read_sectors
|
||||
|
||||
.align 2
|
||||
.global _copy_write_sectors
|
||||
.type _copy_write_sectors,@function
|
||||
|
||||
/* Write a number of words to the ATA data port
|
||||
*
|
||||
* Assumes wordcount to be a multiple of 2.
|
||||
* Writing is not unrolled as much as reading, for several reasons:
|
||||
*
|
||||
* - a similar instruction sequence is faster for writing than for reading
|
||||
* because the auto-incrementing load instructions can be used
|
||||
* - writing profits from warp mode
|
||||
*
|
||||
* Both of these add up to have writing faster than the more unrolled reading.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - buffer address
|
||||
* r5 - word count
|
||||
*
|
||||
* Register usage:
|
||||
* r0/r1 - scratch
|
||||
* r2/r3 - write buffers
|
||||
* r4 - current address
|
||||
* r5 - end address
|
||||
* r6 - mask (if unaligned)
|
||||
* r7 - ata port
|
||||
*/
|
||||
|
||||
_copy_write_sectors:
|
||||
add r5, r5 /* words -> bytes */
|
||||
add r4, r5 /* bytes -> end address */
|
||||
add #-4, r5 /* adjust for offsets */
|
||||
mov.l .ata_data, r7
|
||||
|
||||
mov r4, r0
|
||||
tst #1, r0 /* 16-bit aligned ? */
|
||||
bt .w_aligned /* yes, do word copy */
|
||||
|
||||
/* not 16-bit aligned */
|
||||
mov #-1, r6 /* prepare a bit mask for high byte */
|
||||
shll8 r6 /* r6 = 0xFFFFFF00 */
|
||||
|
||||
mov.b @r4+, r2 /* load (initial old second) first byte */
|
||||
mov.w @r4+, r3 /* load (initial) first word */
|
||||
bra .w_start_b
|
||||
extu.b r2, r0 /* extend unsigned */
|
||||
|
||||
.align 2
|
||||
.w_loop_b: /* main loop: copy 2 words in a row */
|
||||
mov.w @r4+, r3 /* load first word (2+ round) */
|
||||
extu.b r2, r0 /* put away low byte of second word (2+ round) */
|
||||
and r6, r2 /* get high byte of second word (2+ round) */
|
||||
or r1, r2 /* combine with low byte of old first word */
|
||||
mov.w r2, @r7 /* write that */
|
||||
.w_start_b:
|
||||
cmp/hi r4, r5 /* check for end */
|
||||
mov.w @r4+, r2 /* load second word */
|
||||
extu.b r3, r1 /* put away low byte of first word */
|
||||
and r6, r3 /* get high byte of first word */
|
||||
or r0, r3 /* combine with high byte of old second word */
|
||||
mov.w r3, @r7 /* write that */
|
||||
bt .w_loop_b
|
||||
/* 12 instructions for 2 copies, takes 14 clock cycles */
|
||||
/* avg. 7 cycles per word */
|
||||
|
||||
/* the loop "overreads" 1 byte past the buffer end, however, the last */
|
||||
/* byte is not written to disk */
|
||||
and r6, r2 /* get high byte of last word */
|
||||
or r1, r2 /* combine with low byte of old first word */
|
||||
rts
|
||||
mov.w r2, @r7 /* write last word */
|
||||
|
||||
/* 16-bit aligned, loop(load and write word) */
|
||||
.w_aligned:
|
||||
bra .w_start_w /* jump into loop after next instr. */
|
||||
mov.w @r4+, r2 /* load first word (1st round) */
|
||||
|
||||
.align 2
|
||||
.w_loop_w: /* main loop: copy 2 words in a row */
|
||||
mov.w @r4+, r2 /* load first word (2+ round) */
|
||||
swap.b r1, r0 /* swap second word (2+ round) */
|
||||
mov.w r0, @r7 /* write second word (2+ round) */
|
||||
.w_start_w:
|
||||
cmp/hi r4, r5 /* check for end */
|
||||
mov.w @r4+, r1 /* load second word */
|
||||
swap.b r2, r0 /* swap first word */
|
||||
mov.w r0, @r7 /* write first word */
|
||||
bt .w_loop_w
|
||||
/* 8 instructions for 2 copies, takes 10 clock cycles */
|
||||
/* avg. 5 cycles per word */
|
||||
|
||||
swap.b r1, r0 /* swap second word (last round) */
|
||||
rts
|
||||
mov.w r0, @r7 /* and write it */
|
||||
|
||||
.w_end:
|
||||
.size _copy_write_sectors,.w_end-_copy_write_sectors
|
||||
|
||||
.align 2
|
||||
.ata_data:
|
||||
.long 0x06104100 /* ATA data port */
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef ATA_TARGET_H
|
||||
#define ATA_TARGET_H
|
||||
|
||||
/* asm optimised read & write loops */
|
||||
#define ATA_OPTIMIZED_READING
|
||||
#define ATA_OPTIMIZED_WRITING
|
||||
|
||||
#define ATA_SWAP_WORDS
|
||||
|
||||
#define ATA_IOBASE 0x06100100
|
||||
#define ATA_DATA (*((volatile unsigned short*)0x06104100))
|
||||
#define ATA_CONTROL (*ata_control)
|
||||
|
||||
#define ATA_ERROR (*((volatile unsigned char*)ATA_IOBASE + 1))
|
||||
#define ATA_NSECTOR (*((volatile unsigned char*)ATA_IOBASE + 2))
|
||||
#define ATA_SECTOR (*((volatile unsigned char*)ATA_IOBASE + 3))
|
||||
#define ATA_LCYL (*((volatile unsigned char*)ATA_IOBASE + 4))
|
||||
#define ATA_HCYL (*((volatile unsigned char*)ATA_IOBASE + 5))
|
||||
#define ATA_SELECT (*((volatile unsigned char*)ATA_IOBASE + 6))
|
||||
#define ATA_COMMAND (*((volatile unsigned char*)ATA_IOBASE + 7))
|
||||
|
||||
extern volatile unsigned char* ata_control;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,543 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Code that has been in mpeg.c before, now creating an encapsulated play
|
||||
* data module, to be used by other sources than file playback as well.
|
||||
*
|
||||
* Copyright (C) 2004 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "panic.h"
|
||||
#include <kernel.h>
|
||||
#include "mp3_playback.h"
|
||||
#include "sound.h"
|
||||
#include "i2c.h"
|
||||
#include "system.h"
|
||||
#include "audiohw.h"
|
||||
|
||||
/* hacking into mpeg.c, recording is still there */
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
enum
|
||||
{
|
||||
MPEG_DECODER,
|
||||
MPEG_ENCODER
|
||||
} mpeg_mode;
|
||||
#endif /* #ifdef MAS3587F */
|
||||
|
||||
#if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) && !defined(SIMULATOR)
|
||||
extern unsigned long shadow_io_control_main;
|
||||
extern unsigned shadow_codec_reg0;
|
||||
#endif
|
||||
|
||||
/**** globals ****/
|
||||
|
||||
/* own version, independent of mpeg.c */
|
||||
static bool paused; /* playback is paused */
|
||||
static bool playing; /* We are playing an MP3 stream */
|
||||
|
||||
/* the registered callback function to ask for more mp3 data */
|
||||
static mp3_play_callback_t callback_for_more;
|
||||
|
||||
/* list of tracks in memory */
|
||||
#define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
|
||||
#define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
|
||||
|
||||
bool audio_is_initialized = false;
|
||||
|
||||
/* FIX: this code pretty much assumes a MAS */
|
||||
|
||||
/* dirty calls to mpeg.c */
|
||||
extern void playback_tick(void);
|
||||
extern void rec_tick(void);
|
||||
|
||||
unsigned long mas_version_code;
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
static void mas_poll_start(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
count = 9 * FREQ / 10000 / 8; /* 0.9 ms */
|
||||
|
||||
/* We are using timer 1 */
|
||||
|
||||
TSTR &= ~0x02; /* Stop the timer */
|
||||
TSNC &= ~0x02; /* No synchronization */
|
||||
TMDR &= ~0x02; /* Operate normally */
|
||||
|
||||
TCNT1 = 0; /* Start counting at 0 */
|
||||
GRA1 = count;
|
||||
TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
|
||||
|
||||
/* Enable interrupt on level 5 */
|
||||
IPRC = (IPRC & ~0x000f) | 0x0005;
|
||||
|
||||
TSR1 &= ~0x02;
|
||||
TIER1 = 0xf9; /* Enable GRA match interrupt */
|
||||
|
||||
TSTR |= 0x02; /* Start timer 1 */
|
||||
}
|
||||
#elif CONFIG_CODEC != SWCODEC
|
||||
static void postpone_dma_tick(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
count = 8 * FREQ / 10000 / 8; /* 0.8 ms */
|
||||
|
||||
/* We are using timer 1 */
|
||||
|
||||
TSTR &= ~0x02; /* Stop the timer */
|
||||
TSNC &= ~0x02; /* No synchronization */
|
||||
TMDR &= ~0x02; /* Operate normally */
|
||||
|
||||
TCNT1 = 0; /* Start counting at 0 */
|
||||
GRA1 = count;
|
||||
TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
|
||||
|
||||
/* Enable interrupt on level 5 */
|
||||
IPRC = (IPRC & ~0x000f) | 0x0005;
|
||||
|
||||
TSR1 &= ~0x02;
|
||||
TIER1 = 0xf9; /* Enable GRA match interrupt */
|
||||
|
||||
TSTR |= 0x02; /* Start timer 1 */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
void demand_irq_enable(bool on)
|
||||
{
|
||||
int oldlevel = disable_irq_save();
|
||||
|
||||
if(on)
|
||||
{
|
||||
IPRA = (IPRA & 0xfff0) | 0x000b;
|
||||
ICR &= ~0x0010; /* IRQ3 level sensitive */
|
||||
}
|
||||
else
|
||||
IPRA &= 0xfff0;
|
||||
|
||||
restore_irq(oldlevel);
|
||||
}
|
||||
#endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
|
||||
|
||||
static void play_tick(void)
|
||||
{
|
||||
if(playing && !paused)
|
||||
{
|
||||
/* Start DMA if it is disabled and the DEMAND pin is high */
|
||||
if(!(SCR0 & 0x80) && (PBDR & 0x4000))
|
||||
{
|
||||
SCR0 |= 0x80;
|
||||
}
|
||||
|
||||
playback_tick(); /* dirty call to mpeg.c */
|
||||
}
|
||||
}
|
||||
|
||||
void DEI3(void) __attribute__((interrupt_handler));
|
||||
void DEI3(void)
|
||||
{
|
||||
const void* start;
|
||||
size_t size = 0;
|
||||
|
||||
if (callback_for_more != NULL)
|
||||
{
|
||||
callback_for_more(&start, &size);
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
DTCR3 = size & 0xffff;
|
||||
SAR3 = (unsigned int) start;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
|
||||
}
|
||||
|
||||
CHCR3 &= ~0x0002; /* Clear DMA interrupt */
|
||||
}
|
||||
|
||||
void IMIA1(void) __attribute__((interrupt_handler));
|
||||
void IMIA1(void) /* Timer 1 interrupt */
|
||||
{
|
||||
if(playing)
|
||||
play_tick();
|
||||
TSR1 &= ~0x01;
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
/* Disable interrupt */
|
||||
IPRC &= ~0x000f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRQ6(void) __attribute__((interrupt_handler));
|
||||
void IRQ6(void) /* PB14: MAS stop demand IRQ */
|
||||
{
|
||||
SCR0 &= ~0x80;
|
||||
}
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
void IRQ3(void) __attribute__((interrupt_handler));
|
||||
void IRQ3(void) /* PA15: MAS demand IRQ */
|
||||
{
|
||||
/* Begin with setting the IRQ to edge sensitive */
|
||||
ICR |= 0x0010;
|
||||
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
if(mpeg_mode == MPEG_ENCODER)
|
||||
rec_tick();
|
||||
else
|
||||
#endif
|
||||
postpone_dma_tick();
|
||||
|
||||
/* Workaround for sh-elf-gcc 3.3.x bug with -O2 or -Os and ISRs
|
||||
* (invalid cross-jump optimisation) */
|
||||
asm volatile ("");
|
||||
}
|
||||
#endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
|
||||
static void setup_sci0(void)
|
||||
{
|
||||
/* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */
|
||||
PBCR1 = (PBCR1 & 0x0cff) | 0x1208;
|
||||
|
||||
/* Set PB12 to output */
|
||||
or_b(0x10, &PBIORH);
|
||||
|
||||
/* Disable serial port */
|
||||
SCR0 = 0x00;
|
||||
|
||||
/* Synchronous, no prescale */
|
||||
SMR0 = 0x80;
|
||||
|
||||
/* Set baudrate 1Mbit/s */
|
||||
BRR0 = 0x02;
|
||||
|
||||
/* use SCK as serial clock output */
|
||||
SCR0 = 0x01;
|
||||
|
||||
/* Clear FER and PER */
|
||||
SSR0 &= 0xe7;
|
||||
|
||||
/* Set interrupt ITU2 and SCI0 priority to 0 */
|
||||
IPRD &= 0x0ff0;
|
||||
|
||||
/* set PB15 and PB14 to inputs */
|
||||
and_b(~0x80, &PBIORH);
|
||||
and_b(~0x40, &PBIORH);
|
||||
|
||||
/* Enable End of DMA interrupt at prio 8 */
|
||||
IPRC = (IPRC & 0xf0ff) | 0x0800;
|
||||
|
||||
/* Enable Tx (only!) */
|
||||
SCR0 |= 0x20;
|
||||
}
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
static void init_playback(void)
|
||||
{
|
||||
unsigned long val;
|
||||
int rc;
|
||||
|
||||
mp3_play_pause(false);
|
||||
|
||||
mas_reset();
|
||||
|
||||
/* Enable the audio CODEC and the DSP core, max analog voltage range */
|
||||
rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
|
||||
if(rc < 0)
|
||||
panicf("mas_ctrl_w: %d", rc);
|
||||
|
||||
/* Stop the current application */
|
||||
val = 0;
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
|
||||
do
|
||||
{
|
||||
mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
|
||||
} while(val);
|
||||
|
||||
/* Enable the D/A Converter */
|
||||
shadow_codec_reg0 = 0x0001;
|
||||
mas_codec_writereg(0x0, shadow_codec_reg0);
|
||||
|
||||
/* ADC scale 0%, DSP scale 100% */
|
||||
mas_codec_writereg(6, 0x0000);
|
||||
mas_codec_writereg(7, 0x4000);
|
||||
|
||||
#ifdef HAVE_SPDIF_OUT
|
||||
val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
|
||||
#else
|
||||
val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
|
||||
#endif
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
|
||||
|
||||
/* Set Demand mode and validate all settings */
|
||||
shadow_io_control_main = 0x25;
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
|
||||
|
||||
/* Start the Layer2/3 decoder applications */
|
||||
val = 0x0c;
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
|
||||
do
|
||||
{
|
||||
mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
|
||||
} while((val & 0x0c) != 0x0c);
|
||||
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
mpeg_mode = MPEG_DECODER;
|
||||
#endif
|
||||
|
||||
/* set IRQ6 to edge detect */
|
||||
ICR |= 0x02;
|
||||
|
||||
/* set IRQ6 prio 8 */
|
||||
IPRB = ( IPRB & 0xff0f ) | 0x0080;
|
||||
|
||||
DEBUGF("MAS Decoding application started\n");
|
||||
}
|
||||
#endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
|
||||
|
||||
void mp3_init(int volume, int bass, int treble, int balance, int loudness,
|
||||
int avc, int channel_config, int stereo_width,
|
||||
int mdb_strength, int mdb_harmonics,
|
||||
int mdb_center, int mdb_shape, bool mdb_enable,
|
||||
bool superbass)
|
||||
{
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
unsigned long val;
|
||||
(void)loudness;
|
||||
(void)avc;
|
||||
(void)mdb_strength;
|
||||
(void)mdb_harmonics;
|
||||
(void)mdb_center;
|
||||
(void)mdb_shape;
|
||||
(void)mdb_enable;
|
||||
(void)superbass;
|
||||
#endif
|
||||
|
||||
setup_sci0();
|
||||
|
||||
#ifdef HAVE_MAS_SIBI_CONTROL
|
||||
and_b(~0x01, &PBDRH); /* drive SIBI low */
|
||||
or_b(0x01, &PBIORH); /* output for PB8 */
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
mas_reset();
|
||||
#elif CONFIG_CODEC == MAS3587F
|
||||
or_b(0x08, &PAIORH); /* output for /PR */
|
||||
init_playback();
|
||||
|
||||
mas_version_code = mas_readver();
|
||||
DEBUGF("MAS3587 derivate %d, version %c%d\n",
|
||||
(mas_version_code & 0xf000) >> 12,
|
||||
'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
|
||||
#elif CONFIG_CODEC == MAS3539F
|
||||
or_b(0x08, &PAIORH); /* output for /PR */
|
||||
init_playback();
|
||||
|
||||
mas_version_code = mas_readver();
|
||||
DEBUGF("MAS3539 derivate %d, version %c%d\n",
|
||||
(mas_version_code & 0xf000) >> 12,
|
||||
'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DAC3550A
|
||||
dac_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
/* set IRQ6 to edge detect */
|
||||
ICR |= 0x02;
|
||||
|
||||
/* set IRQ6 prio 8 */
|
||||
IPRB = ( IPRB & 0xff0f ) | 0x0080;
|
||||
|
||||
mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1);
|
||||
|
||||
mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
|
||||
mas_run(1);
|
||||
sleep(HZ);
|
||||
|
||||
/* Clear the upper 12 bits of the 32-bit samples */
|
||||
mas_writereg(0xc5, 0);
|
||||
mas_writereg(0xc6, 0);
|
||||
|
||||
/* We need to set the PLL for a 14.31818MHz crystal */
|
||||
if(mas_version_code == 0x0601) /* Version F10? */
|
||||
{
|
||||
val = 0x5d9d0;
|
||||
mas_writemem(MAS_BANK_D0, 0x32d, &val, 1);
|
||||
val = 0xfffceceb;
|
||||
mas_writemem(MAS_BANK_D0, 0x32e, &val, 1);
|
||||
val = 0x0;
|
||||
mas_writemem(MAS_BANK_D0, 0x32f, &val, 1);
|
||||
mas_run(0x475);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = 0x5d9d0;
|
||||
mas_writemem(MAS_BANK_D0, 0x36d, &val, 1);
|
||||
val = 0xfffceceb;
|
||||
mas_writemem(MAS_BANK_D0, 0x36e, &val, 1);
|
||||
val = 0x0;
|
||||
mas_writemem(MAS_BANK_D0, 0x36f, &val, 1);
|
||||
mas_run(0xfcb);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
mas_poll_start();
|
||||
|
||||
mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
|
||||
dac_enable(true);
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
ICR &= ~0x0010; /* IRQ3 level sensitive */
|
||||
PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */
|
||||
#endif
|
||||
|
||||
/* Must be done before calling sound_set() */
|
||||
audio_is_initialized = true;
|
||||
|
||||
sound_set(SOUND_BASS, bass);
|
||||
sound_set(SOUND_TREBLE, treble);
|
||||
sound_set(SOUND_BALANCE, balance);
|
||||
sound_set(SOUND_VOLUME, volume);
|
||||
sound_set(SOUND_CHANNELS, channel_config);
|
||||
sound_set(SOUND_STEREO_WIDTH, stereo_width);
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
sound_set(SOUND_LOUDNESS, loudness);
|
||||
sound_set(SOUND_AVC, avc);
|
||||
sound_set(SOUND_MDB_STRENGTH, mdb_strength);
|
||||
sound_set(SOUND_MDB_HARMONICS, mdb_harmonics);
|
||||
sound_set(SOUND_MDB_CENTER, mdb_center);
|
||||
sound_set(SOUND_MDB_SHAPE, mdb_shape);
|
||||
sound_set(SOUND_MDB_ENABLE, mdb_enable);
|
||||
sound_set(SOUND_SUPERBASS, superbass);
|
||||
#endif
|
||||
|
||||
playing = false;
|
||||
paused = true;
|
||||
}
|
||||
|
||||
void mp3_shutdown(void)
|
||||
{
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
unsigned long val = 1;
|
||||
mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &val, 1); /* Mute */
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
dac_volume(0, 0, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* new functions, to be exported to plugin API */
|
||||
|
||||
#if CONFIG_CODEC == MAS3587F
|
||||
void mp3_play_init(void)
|
||||
{
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
init_playback();
|
||||
#endif
|
||||
playing = false;
|
||||
paused = true;
|
||||
callback_for_more = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void mp3_play_data(const void* start, size_t size,
|
||||
mp3_play_callback_t get_more)
|
||||
{
|
||||
/* init DMA */
|
||||
DAR3 = 0x5FFFEC3;
|
||||
CHCR3 &= ~0x0002; /* Clear interrupt */
|
||||
CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */
|
||||
DMAOR = 0x0001; /* Enable DMA */
|
||||
|
||||
callback_for_more = get_more;
|
||||
|
||||
SAR3 = (unsigned int)start;
|
||||
DTCR3 = size & 0xffff;
|
||||
|
||||
playing = true;
|
||||
paused = true;
|
||||
|
||||
CHCR3 |= 0x0001; /* Enable DMA IRQ */
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
demand_irq_enable(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mp3_play_pause(bool play)
|
||||
{
|
||||
if (paused && play)
|
||||
{ /* resume playback */
|
||||
SCR0 |= 0x80;
|
||||
paused = false;
|
||||
}
|
||||
else if (!paused && !play)
|
||||
{ /* stop playback */
|
||||
SCR0 &= 0x7f;
|
||||
paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool mp3_pause_done(void)
|
||||
{
|
||||
unsigned long frame_count;
|
||||
|
||||
if (!paused)
|
||||
return false;
|
||||
|
||||
mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count, 1);
|
||||
/* This works because the frame counter never wraps,
|
||||
* i.e. zero always means lost sync. */
|
||||
return frame_count == 0;
|
||||
}
|
||||
|
||||
void mp3_play_stop(void)
|
||||
{
|
||||
playing = false;
|
||||
mp3_play_pause(false);
|
||||
CHCR3 &= ~0x0001; /* Disable the DMA interrupt */
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
demand_irq_enable(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mp3_is_playing(void)
|
||||
{
|
||||
return playing;
|
||||
}
|
||||
|
||||
|
||||
/* returns the next byte position which would be transferred */
|
||||
unsigned char* mp3_get_pos(void)
|
||||
{
|
||||
return (unsigned char*)SAR3;
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#include "config.h"
|
||||
|
||||
ENTRY(start)
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
STARTUP(target/sh/crt0.o)
|
||||
|
||||
#define DRAMSIZE (MEMORYSIZE * 0x100000)
|
||||
|
||||
#define DRAMORIG 0x09000000
|
||||
#define IRAMORIG 0x0f000000
|
||||
#define IRAMSIZE 0x1000
|
||||
#define FLASHORIG 0x02000000 + ROM_START
|
||||
#define FLASHSIZE 256K - ROM_START
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
|
||||
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
|
||||
FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vectors :
|
||||
{
|
||||
_datacopy = .;
|
||||
} > FLASH
|
||||
|
||||
.data : AT ( _datacopy )
|
||||
{
|
||||
_datastart = .;
|
||||
KEEP(*(.resetvectors));
|
||||
*(.resetvectors);
|
||||
KEEP(*(.vectors));
|
||||
*(.vectors);
|
||||
. = ALIGN(0x200);
|
||||
*(.icode)
|
||||
*(.irodata)
|
||||
*(.idata)
|
||||
*(.data*)
|
||||
. = ALIGN(0x4);
|
||||
_dataend = .;
|
||||
. = ALIGN(0x10); /* Maintain proper alignment for .text section */
|
||||
} > IRAM
|
||||
|
||||
/* TRICK ALERT! Newer versions of the linker don't allow output sections
|
||||
to overlap even if one of them is empty, so advance the location pointer
|
||||
"by hand" */
|
||||
.text LOADADDR(.data) + SIZEOF(.data) :
|
||||
{
|
||||
*(.init.text)
|
||||
*(.text*)
|
||||
. = ALIGN(0x4);
|
||||
} > FLASH
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata*)
|
||||
. = ALIGN(0x4);
|
||||
_iramcopy = .;
|
||||
} > FLASH
|
||||
|
||||
.stack :
|
||||
{
|
||||
*(.stack)
|
||||
_stackbegin = .;
|
||||
stackbegin = .;
|
||||
. += 0x2000;
|
||||
_stackend = .;
|
||||
stackend = .;
|
||||
} > IRAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
_edata = .;
|
||||
*(.ibss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_end = .;
|
||||
} > IRAM
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2 /* this aligns to 2^2=4 byte bounday */
|
||||
.global _descramble
|
||||
.type _descramble,@function
|
||||
|
||||
/* Descramble a block of byte data, from source to dest, processing len
|
||||
* bytes. Size only limited by the len argument. Note that len must
|
||||
* be an even multiple of 4 (something rolo_load() already assumes.
|
||||
* (Does the Archos firmware loader also require that?).
|
||||
*
|
||||
* Returns the 16-bit "sum" checksum of the descrambled data.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - source (unsigned char*)
|
||||
* r5 - dest (unsigned char*)
|
||||
* r6 - len (unsigned int)
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - data
|
||||
* r1 - temp
|
||||
* r2 - checksum
|
||||
* r3 - current src address
|
||||
* r4 - source
|
||||
* r5 - dest
|
||||
* r6 - len -> source_end
|
||||
* r7 - dest_end
|
||||
* r8 - len / 4
|
||||
*/
|
||||
|
||||
_descramble:
|
||||
mov.l r8,@-r15
|
||||
mov r6,r8
|
||||
shlr2 r8 /* r8 = len / 4 */
|
||||
mov r5,r7
|
||||
add r6,r7 /* dest_end = dest + len */
|
||||
add r4,r6 /* source_end = source + len */
|
||||
mov r4,r3 /* addr = source */
|
||||
mov #0,r2 /* checksum = 0 */
|
||||
|
||||
.loop:
|
||||
mov.b @r3,r0 /* data = *addr */
|
||||
add r8,r3 /* addr += len / 4 */
|
||||
extu.b r0,r0 /* zero extend data byte */
|
||||
swap.b r0,r1 /* byte swap low word to temp */
|
||||
or r1,r0 /* r0's two lower bytes now identical */
|
||||
shlr r0 /* -> this equals "rotr.b r0" now */
|
||||
not r0,r0 /* negate */
|
||||
extu.b r0,r0 /* zero extend low byte (only needed for sum) */
|
||||
mov.b r0,@r5 /* *dest = data */
|
||||
add r0,r2 /* checksum += data */
|
||||
add #1,r5 /* dest++ */
|
||||
cmp/hi r3,r6 /* addr < source_end ? */
|
||||
bt .loop
|
||||
|
||||
add #1,r4 /* source++ */
|
||||
mov r4,r3 /* addr = source */
|
||||
cmp/hi r5,r7 /* dest < dest_end */
|
||||
bt .loop
|
||||
|
||||
/* 15 clock cycles if no reset of source address, 19 if reset,
|
||||
* avg. 16 cycles per byte. Magnus' Version needed 17-22 cycles per byte
|
||||
*/
|
||||
|
||||
mov.l @r15+,r8
|
||||
rts
|
||||
extu.w r2,r0
|
||||
|
||||
|
||||
/* Move len bytes from source to dest (which must be suitably aligned for
|
||||
* long moves) and jump to dest + 0x200.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - source
|
||||
* r5 - dest
|
||||
* r6 - len
|
||||
*/
|
||||
|
||||
.align 2
|
||||
.global _rolo_restart
|
||||
.type _rolo_restart,@function
|
||||
|
||||
_rolo_restart:
|
||||
mov r5,r0
|
||||
sub r4,r0 /* r0 = dest - source */
|
||||
add #-4,r0 /* adjust for early increment */
|
||||
add r4,r6 /* r6 = source + len */
|
||||
|
||||
.copy: /* loop takes 6 cycles per longword */
|
||||
mov.l @r4+,r1
|
||||
cmp/hi r4,r6
|
||||
mov.l r1,@(r0,r4)
|
||||
bt .copy
|
||||
|
||||
mov.l @r5+,r0 /* start address from image */
|
||||
jmp @r0
|
||||
mov.l @r5+,r15 /* stack pointer from image */
|
||||
|
||||
.end:
|
||||
.size _descramble,.end-_descramble
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _ADC_TARGET_H_
|
||||
#define _ADC_TARGET_H_
|
||||
|
||||
#define NUM_ADC_CHANNELS 8
|
||||
|
||||
#define ADC_BATTERY 0 /* Battery voltage always reads 0x3FF due to
|
||||
silly scaling */
|
||||
#define ADC_CHARGE_REGULATOR 0 /* Uh, we read the battery voltage? */
|
||||
#define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */
|
||||
#define ADC_BUTTON_OFF 2 /* the off button, high value if pressed */
|
||||
#define ADC_BUTTON_ON 3 /* the on button, low value if pressed */
|
||||
#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different
|
||||
voltages for different keys */
|
||||
#define ADC_BUTTON_ROW2 5 /* Used for scanning the keys, different
|
||||
voltages for different keys */
|
||||
#define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */
|
||||
#define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */
|
||||
|
||||
#define EXT_SCALE_FACTOR 14800
|
||||
|
||||
#endif /* _ADC_TARGET_H_ */
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef BACKLIGHT_TARGET_H
|
||||
#define BACKLIGHT_TARGET_H
|
||||
|
||||
#include "config.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#define backlight_hw_init() true
|
||||
|
||||
static inline void backlight_hw_on(void)
|
||||
{
|
||||
rtc_write(0x13, 0x10); /* 32 kHz square wave */
|
||||
rtc_write(0x0a, rtc_read(0x0a) | 0x40); /* Enable square wave */
|
||||
}
|
||||
|
||||
static inline void backlight_hw_off(void)
|
||||
{
|
||||
/* While on, backlight is flashing at 32 kHz. If the square wave output
|
||||
is disabled while the backlight is lit, it will become constantly lit,
|
||||
(brighter) and slowly fade. This resets the square wave counter and
|
||||
results in the unlit state */
|
||||
unsigned char rtc_0a = rtc_read(0x0a) & ~0x40;
|
||||
rtc_write(0x0a, rtc_0a); /* Disable square wave */
|
||||
rtc_write(0x13, 0xF0); /* 1 Hz square wave */
|
||||
rtc_write(0x0a, rtc_0a | 0x40); /* Enable square wave */
|
||||
|
||||
/* When the square wave output is disabled in the unlit state,
|
||||
the backlight stays off */
|
||||
rtc_write(0x0a, rtc_0a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
#include "backlight.h"
|
||||
#include "adc.h"
|
||||
|
||||
/*
|
||||
Recorder FM/V2 hardware button hookup
|
||||
=====================================
|
||||
|
||||
F1, F2, F3, UP: connected to AN4 through a resistor network
|
||||
DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5
|
||||
|
||||
The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed
|
||||
FM/V2 has PLAY and RIGHT switched compared to plain recorder
|
||||
|
||||
ON: AN3, low active
|
||||
OFF: AN2, high active
|
||||
*/
|
||||
|
||||
void button_init_device(void)
|
||||
{
|
||||
/* Set PB4 and PB8 as input pins */
|
||||
PBCR1 &= 0xfffc; /* PB8MD = 00 */
|
||||
PBCR2 &= 0xfcff; /* PB4MD = 00 */
|
||||
PBIOR &= ~0x0110; /* Inputs */
|
||||
}
|
||||
|
||||
int button_read_device(void)
|
||||
{
|
||||
int btn = BUTTON_NONE;
|
||||
int data;
|
||||
|
||||
/* check F1..F3 and UP */
|
||||
data = adc_read(ADC_BUTTON_ROW1);
|
||||
if (data >= 150)
|
||||
{
|
||||
if (data >= 545)
|
||||
if (data >= 700)
|
||||
btn = BUTTON_F3;
|
||||
else
|
||||
btn = BUTTON_UP;
|
||||
else
|
||||
if (data >= 385)
|
||||
btn = BUTTON_F2;
|
||||
else
|
||||
btn = BUTTON_F1;
|
||||
}
|
||||
|
||||
/* Some units have mushy keypads, so pressing UP also activates
|
||||
the Left/Right buttons. Let's combat that by skipping the AN5
|
||||
checks when UP is pressed. */
|
||||
if(!(btn & BUTTON_UP))
|
||||
{
|
||||
/* check DOWN, PLAY, LEFT, RIGHT */
|
||||
data = adc_read(ADC_BUTTON_ROW2);
|
||||
if (data >= 150)
|
||||
{
|
||||
if (data >= 545)
|
||||
if (data >= 700)
|
||||
btn |= BUTTON_DOWN;
|
||||
else
|
||||
btn |= BUTTON_RIGHT;
|
||||
else
|
||||
if (data >= 385)
|
||||
btn |= BUTTON_LEFT;
|
||||
else
|
||||
btn |= BUTTON_PLAY;
|
||||
}
|
||||
}
|
||||
|
||||
if ( adc_read(ADC_BUTTON_ON) < 512 )
|
||||
btn |= BUTTON_ON;
|
||||
if ( adc_read(ADC_BUTTON_OFF) > 512 )
|
||||
btn |= BUTTON_OFF;
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _BUTTON_TARGET_H_
|
||||
#define _BUTTON_TARGET_H_
|
||||
|
||||
/* Main unit's buttons */
|
||||
#define BUTTON_ON 0x00000001
|
||||
#define BUTTON_OFF 0x00000002
|
||||
|
||||
#define BUTTON_LEFT 0x00000004
|
||||
#define BUTTON_RIGHT 0x00000008
|
||||
#define BUTTON_UP 0x00000010
|
||||
#define BUTTON_DOWN 0x00000020
|
||||
|
||||
#define BUTTON_PLAY 0x00000040
|
||||
|
||||
#define BUTTON_F1 0x00000080
|
||||
#define BUTTON_F2 0x00000100
|
||||
#define BUTTON_F3 0x00000200
|
||||
|
||||
#define BUTTON_MAIN (BUTTON_ON|BUTTON_OFF|BUTTON_LEFT|BUTTON_RIGHT\
|
||||
|BUTTON_UP|BUTTON_DOWN|BUTTON_PLAY\
|
||||
|BUTTON_F1|BUTTON_F2|BUTTON_F3)
|
||||
|
||||
#define POWEROFF_BUTTON BUTTON_OFF
|
||||
#define POWEROFF_COUNT 10
|
||||
|
||||
#endif /* _BUTTON_TARGET_H_ */
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include <stdbool.h>
|
||||
#include "adc.h"
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if CONFIG_TUNER
|
||||
bool tuner_power(bool status)
|
||||
{
|
||||
(void)status;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* #if CONFIG_TUNER */
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
PBCR2 &= ~0x0c00; /* GPIO for PB5 */
|
||||
or_b(0x20, &PBIORL);
|
||||
or_b(0x20, &PBDRL); /* hold power */
|
||||
}
|
||||
|
||||
unsigned int power_input_status(void)
|
||||
{
|
||||
unsigned int status = POWER_INPUT_NONE;
|
||||
|
||||
/* FM or V2 can also charge from the USB port */
|
||||
if (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF)
|
||||
status = POWER_INPUT_MAIN_CHARGER;
|
||||
|
||||
#ifdef HAVE_USB_POWER
|
||||
if (usb_detect() == USB_INSERTED)
|
||||
status |= POWER_INPUT_USB_CHARGER;
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Returns true if the unit is charging the batteries. */
|
||||
bool charging_state(void)
|
||||
{
|
||||
/* We use the information from the ADC_EXT_POWER ADC channel, which
|
||||
tells us the charging current from the LTC1734. When DC is
|
||||
connected (either via the external adapter, or via USB), we try
|
||||
to determine if it is actively charging or only maintaining the
|
||||
charge. My tests show that ADC readings below about 0x80 means
|
||||
that the LTC1734 is only maintaining the charge. */
|
||||
return adc_read(ADC_EXT_POWER) >= 0x80;
|
||||
}
|
||||
|
||||
void ide_power_enable(bool on)
|
||||
{
|
||||
bool touched = false;
|
||||
|
||||
if(on)
|
||||
{
|
||||
or_b(0x20, &PADRL);
|
||||
touched = true;
|
||||
}
|
||||
#ifdef HAVE_ATA_POWER_OFF
|
||||
if(!on)
|
||||
{
|
||||
and_b(~0x20, &PADRL);
|
||||
touched = true;
|
||||
}
|
||||
#endif /* HAVE_ATA_POWER_OFF */
|
||||
|
||||
/* late port preparation, else problems with read/modify/write
|
||||
of other bits on same port, while input and floating high */
|
||||
if (touched)
|
||||
{
|
||||
or_b(0x20, &PAIORL); /* PA5 is an output */
|
||||
PACR2 &= 0xFBFF; /* GPIO for PA5 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ide_powered(void)
|
||||
{
|
||||
if ((PACR2 & 0x0400) || !(PAIORL & 0x20)) /* not configured for output */
|
||||
return true; /* would be floating high, disk on */
|
||||
else
|
||||
return (PADRL & 0x20) != 0;
|
||||
}
|
||||
|
||||
void power_off(void)
|
||||
{
|
||||
disable_irq();
|
||||
and_b(~0x20, &PBDRL);
|
||||
or_b(0x20, &PBIORL);
|
||||
while(1);
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "adc.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
2800
|
||||
};
|
||||
|
||||
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
2580
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
|
||||
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
|
||||
{
|
||||
/* measured values */
|
||||
{ 2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000 }
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
|
||||
const unsigned short percent_to_volt_charge[11] =
|
||||
{
|
||||
/* TODO: This is identical to the discharge curve.
|
||||
* Calibrate charging curve using a battery_bench log. */
|
||||
2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000
|
||||
};
|
||||
|
||||
/* Battery scale factor (guessed, seems to be 1,25 * value from recorder) */
|
||||
#define BATTERY_SCALE_FACTOR 8275
|
||||
/* full-scale ADC readout (2^10) in millivolt */
|
||||
|
||||
/* Returns battery voltage from ADC [millivolts] */
|
||||
int _battery_voltage(void)
|
||||
{
|
||||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include "adc.h"
|
||||
#include "cpu.h"
|
||||
#include "hwcompat.h"
|
||||
#include "system.h"
|
||||
#include "usb.h"
|
||||
|
||||
int usb_detect(void)
|
||||
{
|
||||
return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED;
|
||||
}
|
||||
|
||||
void usb_enable(bool on)
|
||||
{
|
||||
if(HW_MASK & USB_ACTIVE_HIGH)
|
||||
on = !on;
|
||||
|
||||
if(on)
|
||||
and_b(~0x04, &PADRH); /* enable USB */
|
||||
else
|
||||
or_b(0x04, &PADRH);
|
||||
}
|
||||
|
||||
void usb_init_device(void)
|
||||
{
|
||||
usb_enable(false);
|
||||
or_b(0x04, &PAIORH);
|
||||
}
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "lcd.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "debug.h"
|
||||
#include "system.h"
|
||||
#include "i2c.h"
|
||||
|
||||
/* cute little functions, atomic read-modify-write */
|
||||
|
||||
/* SDA is PB7 */
|
||||
#define SDA_LO and_b(~0x80, &PBDRL)
|
||||
#define SDA_HI or_b(0x80, &PBDRL)
|
||||
#define SDA_INPUT and_b(~0x80, &PBIORL)
|
||||
#define SDA_OUTPUT or_b(0x80, &PBIORL)
|
||||
#define SDA (PBDRL & 0x80)
|
||||
|
||||
#if CONFIG_I2C == I2C_ONDIO
|
||||
/* Ondio pinout, SCL moved to PB6 */
|
||||
#define SCL_INPUT and_b(~0x40, &PBIORL)
|
||||
#define SCL_OUTPUT or_b(0x40, &PBIORL)
|
||||
#define SCL_LO and_b(~0x40, &PBDRL)
|
||||
#define SCL_HI or_b(0x40, &PBDRL)
|
||||
#define SCL (PBDRL & 0x40)
|
||||
#else
|
||||
/* "classic" pinout, SCL is PB13 */
|
||||
#define SCL_INPUT and_b(~0x20, &PBIORH)
|
||||
#define SCL_OUTPUT or_b(0x20, &PBIORH)
|
||||
#define SCL_LO and_b(~0x20, &PBDRH)
|
||||
#define SCL_HI or_b(0x20, &PBDRH)
|
||||
#define SCL (PBDRH & 0x20)
|
||||
#endif
|
||||
|
||||
/* arbitrary delay loop */
|
||||
#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
|
||||
|
||||
static struct mutex i2c_mtx SHAREDBSS_ATTR;
|
||||
|
||||
void i2c_begin(void)
|
||||
{
|
||||
mutex_lock(&i2c_mtx);
|
||||
}
|
||||
|
||||
void i2c_end(void)
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
}
|
||||
|
||||
void i2c_start(void)
|
||||
{
|
||||
SDA_OUTPUT;
|
||||
SDA_HI;
|
||||
SCL_HI;
|
||||
SDA_LO;
|
||||
DELAY;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
void i2c_stop(void)
|
||||
{
|
||||
SDA_LO;
|
||||
SCL_HI;
|
||||
DELAY;
|
||||
SDA_HI;
|
||||
}
|
||||
|
||||
void i2c_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_init(&i2c_mtx);
|
||||
|
||||
#if CONFIG_I2C == I2C_ONDIO
|
||||
/* make PB6 & PB7 general I/O */
|
||||
PBCR2 &= ~0xf000;
|
||||
#else /* not Ondio */
|
||||
/* make PB7 & PB13 general I/O */
|
||||
PBCR1 &= ~0x0c00; /* PB13 */
|
||||
PBCR2 &= ~0xc000; /* PB7 */
|
||||
#endif
|
||||
|
||||
SCL_OUTPUT;
|
||||
SDA_OUTPUT;
|
||||
SDA_HI;
|
||||
SCL_LO;
|
||||
for (i=0;i<3;i++)
|
||||
i2c_stop();
|
||||
}
|
||||
|
||||
void i2c_ack(int bit)
|
||||
{
|
||||
/* Here's the deal. The MAS is slow, and sometimes needs to wait
|
||||
before it can receive the acknowledge. Therefore it forces the clock
|
||||
low until it is ready. We need to poll the clock line until it goes
|
||||
high before we release the ack. */
|
||||
|
||||
SCL_LO; /* Set the clock low */
|
||||
if ( bit )
|
||||
{
|
||||
SDA_HI;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDA_LO;
|
||||
}
|
||||
|
||||
SCL_INPUT; /* Set the clock to input */
|
||||
while(!SCL) /* and wait for the MAS to release it */
|
||||
sleep(0);
|
||||
|
||||
DELAY;
|
||||
SCL_OUTPUT;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
int i2c_getack(void)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
/* Here's the deal. The MAS is slow, and sometimes needs to wait
|
||||
before it can send the acknowledge. Therefore it forces the clock
|
||||
low until it is ready. We need to poll the clock line until it goes
|
||||
high before we read the ack. */
|
||||
|
||||
#ifdef HAVE_I2C_LOW_FIRST
|
||||
SDA_LO; /* First, discharge the data line */
|
||||
#endif
|
||||
SDA_INPUT; /* And set to input */
|
||||
SCL_INPUT; /* Set the clock to input */
|
||||
while(!SCL) /* and wait for the MAS to release it */
|
||||
sleep(0);
|
||||
|
||||
if (SDA)
|
||||
/* ack failed */
|
||||
ret = 0;
|
||||
|
||||
SCL_OUTPUT;
|
||||
SCL_LO;
|
||||
SDA_HI;
|
||||
SDA_OUTPUT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void i2c_outb(unsigned char byte)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* clock out each bit, MSB first */
|
||||
for ( i=0x80; i; i>>=1 ) {
|
||||
if ( i & byte )
|
||||
{
|
||||
SDA_HI;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDA_LO;
|
||||
}
|
||||
SCL_HI;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
SDA_HI;
|
||||
}
|
||||
|
||||
unsigned char i2c_inb(int ack)
|
||||
{
|
||||
int i;
|
||||
unsigned char byte = 0;
|
||||
|
||||
/* clock in each bit, MSB first */
|
||||
for ( i=0x80; i; i>>=1 ) {
|
||||
#ifdef HAVE_I2C_LOW_FIRST
|
||||
/* Tricky business. Here we discharge the data line by driving it low
|
||||
and then set it to input to see if it stays low or goes high */
|
||||
SDA_LO; /* First, discharge the data line */
|
||||
#endif
|
||||
SDA_INPUT; /* And set to input */
|
||||
SCL_HI;
|
||||
if ( SDA )
|
||||
byte |= i;
|
||||
SCL_LO;
|
||||
SDA_OUTPUT;
|
||||
}
|
||||
|
||||
i2c_ack(ack);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
int i2c_write(int address, const unsigned char* buf, int count )
|
||||
{
|
||||
int i,x=0;
|
||||
|
||||
i2c_start();
|
||||
i2c_outb(address & 0xfe);
|
||||
if (i2c_getack())
|
||||
{
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
i2c_outb(buf[i]);
|
||||
if (!i2c_getack())
|
||||
{
|
||||
x=-2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debugf("i2c_write() - no ack\n");
|
||||
x=-1;
|
||||
}
|
||||
i2c_stop();
|
||||
return x;
|
||||
}
|
||||
|
||||
#if 0 /* Currently unused, left for reference and future use */
|
||||
int i2c_read(int address, unsigned char* buf, int count )
|
||||
{
|
||||
int i,x=0;
|
||||
|
||||
i2c_start();
|
||||
i2c_outb(address | 1);
|
||||
if (i2c_getack()) {
|
||||
for (i=0; i<count; i++) {
|
||||
buf[i] = i2c_inb(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
x=-1;
|
||||
i2c_stop();
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Alan Korr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
#include "hwcompat.h"
|
||||
#include "kernel.h"
|
||||
#include "lcd.h"
|
||||
#include "system.h"
|
||||
|
||||
/*** definitions ***/
|
||||
|
||||
#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
|
||||
#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
|
||||
#define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20)
|
||||
#define LCD_SET_POWER_CONTROL_REGISTER ((char)0x28)
|
||||
#define LCD_SET_DISPLAY_START_LINE ((char)0x40)
|
||||
#define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81)
|
||||
#define LCD_SET_SEGMENT_REMAP ((char)0xA0)
|
||||
#define LCD_SET_LCD_BIAS ((char)0xA2)
|
||||
#define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4)
|
||||
#define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5)
|
||||
#define LCD_SET_NORMAL_DISPLAY ((char)0xA6)
|
||||
#define LCD_SET_REVERSE_DISPLAY ((char)0xA7)
|
||||
#define LCD_SET_MULTIPLEX_RATIO ((char)0xA8)
|
||||
#define LCD_SET_BIAS_TC_OSC ((char)0xA9)
|
||||
#define LCD_SET_1OVER4_BIAS_RATIO ((char)0xAA)
|
||||
#define LCD_SET_INDICATOR_OFF ((char)0xAC)
|
||||
#define LCD_SET_INDICATOR_ON ((char)0xAD)
|
||||
#define LCD_SET_DISPLAY_OFF ((char)0xAE)
|
||||
#define LCD_SET_DISPLAY_ON ((char)0xAF)
|
||||
#define LCD_SET_PAGE_ADDRESS ((char)0xB0)
|
||||
#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0)
|
||||
#define LCD_SET_TOTAL_FRAME_PHASES ((char)0xD2)
|
||||
#define LCD_SET_DISPLAY_OFFSET ((char)0xD3)
|
||||
#define LCD_SET_READ_MODIFY_WRITE_MODE ((char)0xE0)
|
||||
#define LCD_SOFTWARE_RESET ((char)0xE2)
|
||||
#define LCD_NOP ((char)0xE3)
|
||||
#define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE ((char)0xEE)
|
||||
|
||||
/* LCD command codes */
|
||||
#define LCD_CNTL_RESET 0xe2 /* Software reset */
|
||||
#define LCD_CNTL_POWER 0x2f /* Power control */
|
||||
#define LCD_CNTL_CONTRAST 0x81 /* Contrast */
|
||||
#define LCD_CNTL_OUTSCAN 0xc8 /* Output scan direction */
|
||||
#define LCD_CNTL_SEGREMAP 0xa1 /* Segment remap */
|
||||
#define LCD_CNTL_DISPON 0xaf /* Display on */
|
||||
|
||||
#define LCD_CNTL_PAGE 0xb0 /* Page address */
|
||||
#define LCD_CNTL_HIGHCOL 0x10 /* Upper column address */
|
||||
#define LCD_CNTL_LOWCOL 0x00 /* Lower column address */
|
||||
|
||||
/** globals **/
|
||||
|
||||
static int xoffset; /* needed for flip */
|
||||
|
||||
/*** hardware configuration ***/
|
||||
|
||||
int lcd_default_contrast(void)
|
||||
{
|
||||
return (HW_MASK & LCD_CONTRAST_BIAS) ? 31 : 49;
|
||||
}
|
||||
|
||||
void lcd_set_contrast(int val)
|
||||
{
|
||||
lcd_write_command(LCD_CNTL_CONTRAST);
|
||||
lcd_write_command(val);
|
||||
}
|
||||
|
||||
void lcd_set_invert_display(bool yesno)
|
||||
{
|
||||
if (yesno)
|
||||
lcd_write_command(LCD_SET_REVERSE_DISPLAY);
|
||||
else
|
||||
lcd_write_command(LCD_SET_NORMAL_DISPLAY);
|
||||
}
|
||||
|
||||
/* turn the display upside down (call lcd_update() afterwards) */
|
||||
void lcd_set_flip(bool yesno)
|
||||
{
|
||||
#ifdef HAVE_DISPLAY_FLIPPED
|
||||
if (!yesno)
|
||||
#else
|
||||
if (yesno)
|
||||
#endif
|
||||
{
|
||||
lcd_write_command(LCD_SET_SEGMENT_REMAP);
|
||||
lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION);
|
||||
xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01);
|
||||
lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08);
|
||||
xoffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_init_device(void)
|
||||
{
|
||||
/* Initialize PB0-3 as output pins */
|
||||
PBCR2 &= 0xff00; /* MD = 00 */
|
||||
PBIOR |= 0x000f; /* IOR = 1 */
|
||||
|
||||
/* inits like the original firmware */
|
||||
lcd_write_command(LCD_SOFTWARE_RESET);
|
||||
lcd_write_command(LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 4);
|
||||
lcd_write_command(LCD_SET_1OVER4_BIAS_RATIO + 0); /* force 1/4 bias: 0 */
|
||||
lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7);
|
||||
/* power control register: op-amp=1, regulator=1, booster=1 */
|
||||
lcd_write_command(LCD_SET_DISPLAY_ON);
|
||||
lcd_write_command(LCD_SET_NORMAL_DISPLAY);
|
||||
lcd_set_flip(false);
|
||||
lcd_write_command(LCD_SET_DISPLAY_START_LINE + 0);
|
||||
lcd_set_contrast(lcd_default_contrast());
|
||||
lcd_write_command(LCD_SET_PAGE_ADDRESS);
|
||||
lcd_write_command(LCD_SET_LOWER_COLUMN_ADDRESS + 0);
|
||||
lcd_write_command(LCD_SET_HIGHER_COLUMN_ADDRESS + 0);
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_update();
|
||||
}
|
||||
|
||||
/*** Update functions ***/
|
||||
|
||||
/* Performance function that works with an external buffer
|
||||
note that by and bheight are in 8-pixel units! */
|
||||
void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
|
||||
int bheight, int stride)
|
||||
{
|
||||
/* Copy display bitmap to hardware */
|
||||
while (bheight--)
|
||||
{
|
||||
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
|
||||
lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf));
|
||||
lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf));
|
||||
|
||||
lcd_write_data(data, width);
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function for lcd_grey_phase_blit(). */
|
||||
void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
|
||||
|
||||
/* Performance function that works with an external buffer
|
||||
note that by and bheight are in 8-pixel units! */
|
||||
void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
|
||||
int x, int by, int width, int bheight, int stride)
|
||||
{
|
||||
stride <<= 3; /* 8 pixels per block */
|
||||
while (bheight--)
|
||||
{
|
||||
lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
|
||||
lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf));
|
||||
lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf));
|
||||
|
||||
lcd_grey_data(values, phases, width);
|
||||
values += stride;
|
||||
phases += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update the display.
|
||||
This must be called after all other LCD functions that change the display. */
|
||||
void lcd_update(void)
|
||||
{
|
||||
int y;
|
||||
|
||||
/* Copy display bitmap to hardware */
|
||||
for (y = 0; y < LCD_FBHEIGHT; y++)
|
||||
{
|
||||
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
|
||||
lcd_write_command (LCD_CNTL_HIGHCOL | ((xoffset >> 4) & 0xf));
|
||||
lcd_write_command (LCD_CNTL_LOWCOL | (xoffset & 0xf));
|
||||
|
||||
lcd_write_data (FBADDR(0, y), LCD_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x, int y, int width, int height)
|
||||
{
|
||||
int ymax;
|
||||
|
||||
/* The Y coordinates have to work on even 8 pixel rows */
|
||||
ymax = (y + height-1) >> 3;
|
||||
y >>= 3;
|
||||
|
||||
if(x + width > LCD_WIDTH)
|
||||
width = LCD_WIDTH - x;
|
||||
if (width <= 0)
|
||||
return; /* nothing left to do, 0 is harmful to lcd_write_data() */
|
||||
if(ymax >= LCD_FBHEIGHT)
|
||||
ymax = LCD_FBHEIGHT-1;
|
||||
|
||||
/* Copy specified rectange bitmap to hardware */
|
||||
for (; y <= ymax; y++)
|
||||
{
|
||||
lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
|
||||
lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset) >> 4) & 0xf));
|
||||
lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf));
|
||||
|
||||
lcd_write_data (FBADDR(x,y), width);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,354 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
* Based on the work of Alan Korr and Jörg Hohensohn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define LCDR (PBDR_ADDR+1)
|
||||
|
||||
#define LCD_SD 1 /* PB0 = 1 --- 0001 */
|
||||
#define LCD_SC 2 /* PB1 = 1 --- 0010 */
|
||||
#define LCD_DS 4 /* PB2 = 1 --- 0100 */
|
||||
#define LCD_CS 8 /* PB3 = 1 --- 1000 */
|
||||
|
||||
/*
|
||||
* About /CS,DS,SC,SD
|
||||
* ------------------
|
||||
*
|
||||
* LCD on JBP and JBR uses a SPI protocol to receive orders (SDA and SCK lines)
|
||||
*
|
||||
* - /CS -> Chip Selection line :
|
||||
* 0 : LCD chipset is activated.
|
||||
* - DS -> Data Selection line, latched at the rising edge
|
||||
* of the 8th serial clock (*) :
|
||||
* 0 : instruction register,
|
||||
* 1 : data register;
|
||||
* - SC -> Serial Clock line (SDA).
|
||||
* - SD -> Serial Data line (SCK), latched at the rising edge
|
||||
* of each serial clock (*).
|
||||
*
|
||||
* _ _
|
||||
* /CS \ /
|
||||
* \______________________________________________________/
|
||||
* _____ ____ ____ ____ ____ ____ ____ ____ ____ _____
|
||||
* SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/
|
||||
* _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____
|
||||
*
|
||||
* _____ _ _ _ _ _ _ _ ________
|
||||
* SC \ * \ * \ * \ * \ * \ * \ * \ *
|
||||
* \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
||||
* _ _________________________________________________________
|
||||
* DS \/
|
||||
* _/\_________________________________________________________
|
||||
*
|
||||
*/
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _lcd_write_command
|
||||
.type _lcd_write_command,@function
|
||||
|
||||
/* Write a command byte to the lcd controller
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - data byte (int)
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1 - data byte (copied)
|
||||
* r2 - precalculated port value (CS, DS and SC low, SD high),
|
||||
* negated (neg)!
|
||||
* r3 - lcd port address
|
||||
* r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
|
||||
*/
|
||||
|
||||
_lcd_write_command:
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
mov r4, r1 /* copy data byte to r1 */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
mov #0, r5 /* fake end address - stop after first iteration */
|
||||
or #(LCD_SD), r0 /* r0 |= LCD_SD */
|
||||
and #(~(LCD_CS|LCD_DS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
|
||||
|
||||
bra .single_transfer /* jump into the transfer loop */
|
||||
neg r0, r2 /* r2 = 0 - r0 */
|
||||
|
||||
|
||||
.align 2
|
||||
.global _lcd_write_data
|
||||
.type _lcd_write_data,@function
|
||||
|
||||
/* A high performance function to write data to the display,
|
||||
* one or multiple bytes.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - data address
|
||||
* r5 - byte count
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1 - current data byte
|
||||
* r2 - precalculated port value (CS and SC low, DS and SD high),
|
||||
* negated (neg)!
|
||||
* r3 - lcd port address
|
||||
*/
|
||||
|
||||
_lcd_write_data:
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
add r4, r5 /* end address */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. If disabling interrupts
|
||||
* for a long time (~9200 clks = ~830 µs for transferring 112 bytes on
|
||||
* recorders)is undesirable, the loop has to be rewritten to
|
||||
* disable/precalculate/transfer/enable for each iteration. However,
|
||||
* this would significantly decrease performance. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
|
||||
and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
||||
neg r0, r2 /* r2 = 0 - r0 */
|
||||
|
||||
/* loop exploits that SD is on bit 0 for recorders and Ondios */
|
||||
|
||||
.align 2
|
||||
.multi_transfer:
|
||||
mov.b @r4+, r1 /* load data byte from memory */
|
||||
nop
|
||||
|
||||
.single_transfer:
|
||||
shll16 r1 /* shift data to most significant byte */
|
||||
shll8 r1
|
||||
not r1, r1 /* and invert for use with negc */
|
||||
|
||||
shll r1 /* shift the MSB into carry */
|
||||
negc r2, r0 /* carry to SD, SC low */
|
||||
shll r1 /* next shift here for alignment */
|
||||
mov.b r0, @r3 /* set data to port */
|
||||
or #(LCD_SC), r0 /* rise SC (independent of SD level) */
|
||||
mov.b r0, @r3 /* set to port */
|
||||
|
||||
negc r2, r0
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
negc r2, r0
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
negc r2, r0
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
negc r2, r0
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
negc r2, r0
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
negc r2, r0
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
negc r2, r0
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
cmp/hi r4, r5 /* some blocks left? */
|
||||
bt .multi_transfer
|
||||
|
||||
or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0 /* restore port */
|
||||
rts
|
||||
mov.b r0, @r3
|
||||
|
||||
/* This is the place to reenable the interrupts, if we have disabled
|
||||
* them. See above. */
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
.align 2
|
||||
.global _lcd_grey_data
|
||||
.type _lcd_grey_data,@function
|
||||
|
||||
/* A high performance function to write grey phase data to the display,
|
||||
* one or multiple pixels.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - pixel value data address
|
||||
* r5 - pixel phase data address
|
||||
* r6 - pixel block count
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch / phase signs mask
|
||||
* r1 - scratch
|
||||
* r2 - precalculated port value (CS and SC low, DS and SD high),
|
||||
* negated (neg)!
|
||||
* r3 - lcd port address
|
||||
* r4 - current value address
|
||||
* r5 - current phase address
|
||||
* r6 - end address
|
||||
* r7/r8 - current/next block of phases (alternating)
|
||||
* r9/r10 - current blocks of values
|
||||
* r11 - 0x00000080 \
|
||||
* r12 - 0x00008000 > for phase sign check
|
||||
* r13 - 0x00800000 /
|
||||
*/
|
||||
|
||||
_lcd_grey_data:
|
||||
mov.l r8, @-r15 /* save r8 */
|
||||
mov.l r9, @-r15 /* save r9 */
|
||||
mov.l r10, @-r15 /* save r10 */
|
||||
shll2 r6 /* v */
|
||||
mov.l r11, @-r15 /* save r11 */
|
||||
shll r6 /* r6 *= 8; (8 pixels per block) */
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
add r4, r6 /* end address */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. If disabling interrupts
|
||||
* for a long time is undesirable, the loop has to be rewritten to
|
||||
* disable/precalculate/transfer/enable for each iteration. However,
|
||||
* this would significantly decrease performance. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
|
||||
mov.l r12, @-r15 /* save r12 */
|
||||
and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
||||
mov.l r13, @-r15 /* save r13 */
|
||||
neg r0, r2 /* r2 = 0 - r0 */
|
||||
|
||||
/* loop exploits that SD is on bit 0 for recorders and Ondios */
|
||||
|
||||
mov.w .ptest, r11
|
||||
swap.b r11, r12
|
||||
mov.l @r5, r7
|
||||
swap.w r11, r13
|
||||
mov.l .pmask, r0
|
||||
|
||||
.greyloop:
|
||||
cmp/pz r7
|
||||
mov.l @r4+, r9
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r13, r7
|
||||
mov.l @r4+, r10
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r12, r7
|
||||
mov.l @(4,r5), r8
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r11, r7
|
||||
or r0, r7
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
cmp/pz r8
|
||||
sub r9, r7
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r13, r8
|
||||
mov.l r7, @r5
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r12, r8
|
||||
mov.l @(8,r5), r7
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
tst r11, r8
|
||||
or r0, r8
|
||||
negc r2, r1
|
||||
mov.b r1, @r3
|
||||
add #(LCD_SC), r1
|
||||
mov.b r1, @r3
|
||||
|
||||
sub r10, r8
|
||||
mov.l r8, @(4,r5)
|
||||
|
||||
add #8, r5
|
||||
cmp/hi r4, r6
|
||||
bt .greyloop
|
||||
|
||||
mov.l @r15+, r13 /* restore r13 */
|
||||
mov #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0
|
||||
mov.l @r15+, r12 /* restore r12 */
|
||||
or r0, r1 /* restore port */
|
||||
mov.l @r15+, r11 /* restore r11 */
|
||||
mov.l @r15+, r10 /* restore r10 */
|
||||
mov.l @r15+, r9 /* restore r9 */
|
||||
mov.l @r15+, r8 /* restore r8 */
|
||||
rts
|
||||
mov.b r1, @r3
|
||||
|
||||
/* This is the place to reenable the interrupts, if we have disabled
|
||||
* them. See above. */
|
||||
|
||||
.ptest:
|
||||
.short 0x0080
|
||||
|
||||
.align 2
|
||||
.pmask:
|
||||
.long 0x80808080
|
||||
#endif
|
||||
|
||||
.align 2
|
||||
.lcdr:
|
||||
.long LCDR
|
||||
|
|
@ -1,491 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "stdbool.h"
|
||||
#include "config.h"
|
||||
#include "sh7034.h"
|
||||
#include "i2c.h"
|
||||
#include "debug.h"
|
||||
#include "mas35xx.h"
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "hwcompat.h"
|
||||
|
||||
static int mas_devread(unsigned long *dest, int len);
|
||||
|
||||
#if 0 /* Currently unused, left for reference and future use */
|
||||
int mas_default_read(unsigned short *buf)
|
||||
{
|
||||
unsigned char *dest = (unsigned char *)buf;
|
||||
int ret = 0;
|
||||
|
||||
i2c_begin();
|
||||
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_WRITE);
|
||||
if (i2c_getack()) {
|
||||
i2c_outb(MAS_DATA_READ);
|
||||
if (i2c_getack()) {
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_READ);
|
||||
if (i2c_getack()) {
|
||||
dest[0] = i2c_inb(0);
|
||||
dest[1] = i2c_inb(1);
|
||||
}
|
||||
else
|
||||
ret = -3;
|
||||
}
|
||||
else
|
||||
ret = -2;
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
i2c_stop();
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
int mas_run(unsigned short address)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[3];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_DATA_WRITE;
|
||||
buf[1] = address >> 8;
|
||||
buf[2] = address & 0xff;
|
||||
|
||||
/* send run command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,3))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* note: 'len' is number of 32-bit words, not number of bytes! */
|
||||
int mas_readmem(int bank, int addr, unsigned long* dest, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[7];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_DATA_WRITE;
|
||||
buf[1] = bank?MAS_CMD_READ_D1_MEM:MAS_CMD_READ_D0_MEM;
|
||||
buf[2] = 0x00;
|
||||
buf[3] = (len & 0xff00) >> 8;
|
||||
buf[4] = len & 0xff;
|
||||
buf[5] = (addr & 0xff00) >> 8;
|
||||
buf[6] = addr & 0xff;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,7))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
ret = mas_devread(dest, len);
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* note: 'len' is number of 32-bit words, not number of bytes! */
|
||||
int mas_writemem(int bank, int addr, const unsigned long* src, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
int i, j;
|
||||
unsigned char buf[60];
|
||||
const unsigned char* ptr = (const unsigned char*)src;
|
||||
|
||||
i2c_begin();
|
||||
|
||||
i=0;
|
||||
buf[i++] = MAS_DATA_WRITE;
|
||||
buf[i++] = bank?MAS_CMD_WRITE_D1_MEM:MAS_CMD_WRITE_D0_MEM;
|
||||
buf[i++] = 0x00;
|
||||
buf[i++] = (len & 0xff00) >> 8;
|
||||
buf[i++] = len & 0xff;
|
||||
buf[i++] = (addr & 0xff00) >> 8;
|
||||
buf[i++] = addr & 0xff;
|
||||
|
||||
j = 0;
|
||||
while(len--) {
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
buf[i++] = 0;
|
||||
buf[i++] = ptr[j+1];
|
||||
buf[i++] = ptr[j+2];
|
||||
buf[i++] = ptr[j+3];
|
||||
#else
|
||||
buf[i++] = ptr[j+2];
|
||||
buf[i++] = ptr[j+3];
|
||||
buf[i++] = 0;
|
||||
buf[i++] = ptr[j+1];
|
||||
#endif
|
||||
j += 4;
|
||||
}
|
||||
|
||||
/* send write command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,i))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mas_readreg(int reg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[16];
|
||||
unsigned long value;
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_DATA_WRITE;
|
||||
buf[1] = MAS_CMD_READ_REG | (reg >> 4);
|
||||
buf[2] = (reg & 0x0f) << 4;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,3))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mas_devread(&value, 1))
|
||||
{
|
||||
ret = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = value;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mas_writereg(int reg, unsigned int val)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[5];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_DATA_WRITE;
|
||||
buf[1] = MAS_CMD_WRITE_REG | (reg >> 4);
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
buf[2] = ((reg & 0x0f) << 4) | (val >> 16 & 0x0f);
|
||||
buf[3] = (val >> 8) & 0xff;
|
||||
buf[4] = val & 0xff;
|
||||
#else
|
||||
buf[2] = ((reg & 0x0f) << 4) | (val & 0x0f);
|
||||
buf[3] = (val >> 12) & 0xff;
|
||||
buf[4] = (val >> 4) & 0xff;
|
||||
#endif
|
||||
|
||||
/* send write command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,5))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* note: 'len' is number of 32-bit words, not number of bytes! */
|
||||
static int mas_devread(unsigned long *dest, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char* ptr = (unsigned char*)dest;
|
||||
int i;
|
||||
|
||||
/* handle read-back */
|
||||
/* Remember, the MAS values are only 20 bits, so we set
|
||||
the upper 12 bits to 0 */
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_WRITE);
|
||||
if (i2c_getack()) {
|
||||
i2c_outb(MAS_DATA_READ);
|
||||
if (i2c_getack()) {
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_READ);
|
||||
if (i2c_getack()) {
|
||||
for (i=0;len;i++) {
|
||||
len--;
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
i2c_inb(0); /* Dummy read */
|
||||
ptr[i*4+0] = 0;
|
||||
ptr[i*4+1] = i2c_inb(0) & 0x0f;
|
||||
ptr[i*4+2] = i2c_inb(0);
|
||||
if(len)
|
||||
ptr[i*4+3] = i2c_inb(0);
|
||||
else
|
||||
ptr[i*4+3] = i2c_inb(1); /* NAK the last byte */
|
||||
#else
|
||||
ptr[i*4+2] = i2c_inb(0);
|
||||
ptr[i*4+3] = i2c_inb(0);
|
||||
ptr[i*4+0] = i2c_inb(0);
|
||||
if(len)
|
||||
ptr[i*4+1] = i2c_inb(0);
|
||||
else
|
||||
ptr[i*4+1] = i2c_inb(1); /* NAK the last byte */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = -3;
|
||||
}
|
||||
else
|
||||
ret = -2;
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mas_reset(void)
|
||||
{
|
||||
or_b(0x01, &PAIORH);
|
||||
|
||||
#if CONFIG_CODEC == MAS3507D
|
||||
/* PB5 is "MAS enable". make it GPIO output and high */
|
||||
PBCR2 &= ~0x0c00;
|
||||
or_b(0x20, &PBIORL);
|
||||
or_b(0x20, &PBDRL);
|
||||
|
||||
and_b(~0x01, &PADRH);
|
||||
sleep(HZ/100);
|
||||
or_b(0x01, &PADRH);
|
||||
sleep(HZ/5);
|
||||
#elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
if (HW_MASK & ATA_ADDRESS_200)
|
||||
{
|
||||
and_b(~0x01, &PADRH);
|
||||
sleep(HZ/100);
|
||||
or_b(0x01, &PADRH);
|
||||
sleep(HZ/5);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Older recorder models don't invert the POR signal */
|
||||
or_b(0x01, &PADRH);
|
||||
sleep(HZ/100);
|
||||
and_b(~0x01, &PADRH);
|
||||
sleep(HZ/5);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
|
||||
#if 0 /* Currently unused, left for reference and future use */
|
||||
int mas_direct_config_read(unsigned char reg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char tmp[2];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_WRITE);
|
||||
if (i2c_getack()) {
|
||||
i2c_outb(reg);
|
||||
if (i2c_getack()) {
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_READ);
|
||||
if (i2c_getack()) {
|
||||
tmp[0] = i2c_inb(0);
|
||||
tmp[1] = i2c_inb(1); /* NAK the last byte */
|
||||
ret = (tmp[0] << 8) | tmp[1];
|
||||
}
|
||||
else
|
||||
ret = -3;
|
||||
}
|
||||
else
|
||||
ret = -2;
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
i2c_stop();
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mas_direct_config_write(unsigned char reg, unsigned int val)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[3];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = reg;
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
buf[2] = val & 0xff;
|
||||
|
||||
/* send write command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,3))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mas_codec_writereg(int reg, unsigned int val)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[5];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_CODEC_WRITE;
|
||||
buf[1] = (reg >> 8) & 0xff;
|
||||
buf[2] = reg & 0xff;
|
||||
buf[3] = (val >> 8) & 0xff;
|
||||
buf[4] = val & 0xff;
|
||||
|
||||
/* send write command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,5))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mas_codec_readreg(int reg)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[16];
|
||||
unsigned char tmp[2];
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_CODEC_WRITE;
|
||||
buf[1] = (reg >> 8) & 0xff;
|
||||
buf[2] = reg & 0xff;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,3))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_WRITE);
|
||||
if (i2c_getack()) {
|
||||
i2c_outb(MAS_CODEC_READ);
|
||||
if (i2c_getack()) {
|
||||
i2c_start();
|
||||
i2c_outb(MAS_DEV_READ);
|
||||
if (i2c_getack()) {
|
||||
tmp[0] = i2c_inb(0);
|
||||
tmp[1] = i2c_inb(1); /* NAK the last byte */
|
||||
ret = (tmp[0] << 8) | tmp[1];
|
||||
}
|
||||
else
|
||||
ret = -4;
|
||||
}
|
||||
else
|
||||
ret = -3;
|
||||
}
|
||||
else
|
||||
ret = -2;
|
||||
|
||||
i2c_stop();
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned long mas_readver(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char buf[16];
|
||||
unsigned long value;
|
||||
|
||||
i2c_begin();
|
||||
|
||||
buf[0] = MAS_DATA_WRITE;
|
||||
buf[1] = MAS_CMD_READ_IC_VER;
|
||||
buf[2] = 0;
|
||||
|
||||
/* send read command */
|
||||
if (i2c_write(MAS_DEV_WRITE,buf,3))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mas_devread(&value, 1))
|
||||
{
|
||||
ret = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = value;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_TUNER & S1A0903X01
|
||||
static int pllfreq;
|
||||
|
||||
void mas_store_pllfreq(int freq)
|
||||
{
|
||||
pllfreq = freq;
|
||||
}
|
||||
|
||||
int mas_get_pllfreq(void)
|
||||
{
|
||||
return pllfreq;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _ADC_TARGET_H_
|
||||
#define _ADC_TARGET_H_
|
||||
|
||||
#define NUM_ADC_CHANNELS 8
|
||||
|
||||
#define ADC_MMC_SWITCH 0 /* low values if MMC inserted */
|
||||
#define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */
|
||||
#define ADC_BUTTON_OPTION 2 /* the option button, low value if pressed */
|
||||
#define ADC_BUTTON_ONOFF 3 /* the on/off button, high value if pressed */
|
||||
#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different
|
||||
voltages for different keys */
|
||||
#define ADC_USB_ACTIVE 5 /* USB bridge activity */
|
||||
#define ADC_UNREG_POWER 7 /* Battery voltage */
|
||||
|
||||
#define EXT_SCALE_FACTOR 14800
|
||||
|
||||
#endif /* _ADC_TARGET_H_ */
|
||||
|
|
@ -1,978 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "ata_mmc.h"
|
||||
#include "sdmmc.h"
|
||||
#include "kernel.h"
|
||||
#include "led.h"
|
||||
#include "sh7034.h"
|
||||
#include "system.h"
|
||||
#include "debug.h"
|
||||
#include "panic.h"
|
||||
#include "power.h"
|
||||
#include "string.h"
|
||||
#include "hwcompat.h"
|
||||
#include "adc.h"
|
||||
#include "bitswap.h"
|
||||
#include "storage.h"
|
||||
|
||||
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
#define MMC_NUM_DRIVES 2
|
||||
#else
|
||||
#define MMC_NUM_DRIVES 1
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE 512 /* fixed */
|
||||
|
||||
/* Command definitions */
|
||||
#define CMD_GO_IDLE_STATE 0x40 /* R1 */
|
||||
#define CMD_SEND_OP_COND 0x41 /* R1 */
|
||||
#define CMD_SEND_CSD 0x49 /* R1 */
|
||||
#define CMD_SEND_CID 0x4a /* R1 */
|
||||
#define CMD_STOP_TRANSMISSION 0x4c /* R1 */
|
||||
#define CMD_SEND_STATUS 0x4d /* R2 */
|
||||
#define CMD_SET_BLOCKLEN 0x50 /* R1 */
|
||||
#define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */
|
||||
#define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */
|
||||
#define CMD_WRITE_BLOCK 0x58 /* R1b */
|
||||
#define CMD_WRITE_MULTIPLE_BLOCK 0x59 /* R1b */
|
||||
#define CMD_READ_OCR 0x7a /* R3 */
|
||||
|
||||
/* Response formats:
|
||||
R1 = single byte, msb=0, various error flags
|
||||
R1b = R1 + busy token(s)
|
||||
R2 = 2 bytes (1st byte identical to R1), additional flags
|
||||
R3 = 5 bytes (R1 + OCR register)
|
||||
*/
|
||||
|
||||
#define R1_PARAMETER_ERR 0x40
|
||||
#define R1_ADDRESS_ERR 0x20
|
||||
#define R1_ERASE_SEQ_ERR 0x10
|
||||
#define R1_COM_CRC_ERR 0x08
|
||||
#define R1_ILLEGAL_CMD 0x04
|
||||
#define R1_ERASE_RESET 0x02
|
||||
#define R1_IN_IDLE_STATE 0x01
|
||||
|
||||
#define R2_OUT_OF_RANGE 0x80
|
||||
#define R2_ERASE_PARAM 0x40
|
||||
#define R2_WP_VIOLATION 0x20
|
||||
#define R2_CARD_ECC_FAIL 0x10
|
||||
#define R2_CC_ERROR 0x08
|
||||
#define R2_ERROR 0x04
|
||||
#define R2_ERASE_SKIP 0x02
|
||||
#define R2_CARD_LOCKED 0x01
|
||||
|
||||
/* Data start tokens */
|
||||
|
||||
#define DT_START_BLOCK 0xfe
|
||||
#define DT_START_WRITE_MULTIPLE 0xfc
|
||||
#define DT_STOP_TRAN 0xfd
|
||||
|
||||
/* for compatibility */
|
||||
static long last_disk_activity = -1;
|
||||
|
||||
/* private variables */
|
||||
|
||||
#ifdef CONFIG_STORAGE_MULTI
|
||||
static int mmc_first_drive = 0;
|
||||
#else
|
||||
#define mmc_first_drive 0
|
||||
#endif
|
||||
|
||||
static struct mutex mmc_mutex SHAREDBSS_ATTR;
|
||||
|
||||
static bool initialized = false;
|
||||
static bool new_mmc_circuit;
|
||||
|
||||
static enum {
|
||||
MMC_UNKNOWN,
|
||||
MMC_UNTOUCHED,
|
||||
MMC_TOUCHED
|
||||
} mmc_status = MMC_UNKNOWN;
|
||||
|
||||
static enum {
|
||||
SER_POLL_WRITE,
|
||||
SER_POLL_READ,
|
||||
SER_DISABLED
|
||||
} serial_mode;
|
||||
|
||||
static const unsigned char dummy[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
/* 2 buffers used alternatively for writing, including start token,
|
||||
* dummy CRC and an extra byte to keep word alignment. */
|
||||
static unsigned char write_buffer[2][BLOCK_SIZE+4];
|
||||
static int current_buffer = 0;
|
||||
static const unsigned char *send_block_addr = NULL;
|
||||
|
||||
static tCardInfo card_info[2];
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
static int current_card = 0;
|
||||
#endif
|
||||
static bool last_mmc_status = false;
|
||||
static int countdown = -1; /* for mmc switch debouncing. -1 because the
|
||||
countdown should not happen if the card
|
||||
is inserted at boot */
|
||||
static bool usb_activity; /* monitoring the USB bridge */
|
||||
static long last_usb_activity;
|
||||
|
||||
/* private function declarations */
|
||||
|
||||
static int select_card(int card_no);
|
||||
static void deselect_card(void);
|
||||
static void setup_sci1(int bitrate_register);
|
||||
static void set_sci1_poll_read(void);
|
||||
static void write_transfer(const unsigned char *buf, int len)
|
||||
__attribute__ ((section(".icode")));
|
||||
static void read_transfer(unsigned char *buf, int len)
|
||||
__attribute__ ((section(".icode")));
|
||||
static unsigned char poll_byte(long timeout);
|
||||
static unsigned char poll_busy(long timeout);
|
||||
static unsigned char send_cmd(int cmd, unsigned long parameter, void *data);
|
||||
static int receive_cxd(unsigned char *buf);
|
||||
static int initialize_card(int card_no);
|
||||
static int receive_block(unsigned char *inbuf, long timeout);
|
||||
static void send_block_prepare(void);
|
||||
static int send_block_send(unsigned char start_token, long timeout,
|
||||
bool prepare_next);
|
||||
static void mmc_tick(void);
|
||||
|
||||
/* implementation */
|
||||
|
||||
static void enable_controller(bool on)
|
||||
{
|
||||
PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
|
||||
* if not modified below */
|
||||
if (on)
|
||||
PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
|
||||
|
||||
and_b(~0x80, &PADRL); /* assert flash reset */
|
||||
sleep(HZ/100);
|
||||
or_b(0x80, &PADRL); /* de-assert flash reset */
|
||||
sleep(HZ/100);
|
||||
card_info[0].initialized = false;
|
||||
card_info[1].initialized = false;
|
||||
}
|
||||
|
||||
void mmc_enable_int_flash_clock(bool on)
|
||||
{
|
||||
/* Internal flash clock is enabled by setting PA12 high with the new
|
||||
* clock circuit, and by setting it low with the old clock circuit */
|
||||
if (on ^ new_mmc_circuit)
|
||||
and_b(~0x10, &PADRH); /* clear clock gate PA12 */
|
||||
else
|
||||
or_b(0x10, &PADRH); /* set clock gate PA12 */
|
||||
}
|
||||
|
||||
static int select_card(int card_no)
|
||||
{
|
||||
mutex_lock(&mmc_mutex);
|
||||
led(true);
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
mmc_enable_int_flash_clock(card_no == 0);
|
||||
|
||||
if (!card_info[card_no].initialized)
|
||||
{
|
||||
setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
|
||||
write_transfer(dummy, 10); /* allow the card to synchronize */
|
||||
while (!(SSR1 & SCI_TEND));
|
||||
}
|
||||
|
||||
if (card_no == 0) /* internal */
|
||||
and_b(~0x04, &PADRH); /* assert CS */
|
||||
else /* external */
|
||||
and_b(~0x02, &PADRH); /* assert CS */
|
||||
|
||||
if (card_info[card_no].initialized)
|
||||
{
|
||||
setup_sci1(card_info[card_no].bitrate_register);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return initialize_card(card_no);
|
||||
}
|
||||
}
|
||||
|
||||
static void deselect_card(void)
|
||||
{
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
or_b(0x06, &PADRH); /* deassert CS (both cards) */
|
||||
|
||||
led(false);
|
||||
mutex_unlock(&mmc_mutex);
|
||||
last_disk_activity = current_tick;
|
||||
}
|
||||
|
||||
static void setup_sci1(int bitrate_register)
|
||||
{
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
|
||||
SCR1 = 0; /* disable serial port */
|
||||
SMR1 = SYNC_MODE; /* no prescale */
|
||||
BRR1 = bitrate_register;
|
||||
SSR1 = 0;
|
||||
|
||||
SCR1 = SCI_TE; /* enable transmitter */
|
||||
serial_mode = SER_POLL_WRITE;
|
||||
}
|
||||
|
||||
static void set_sci1_poll_read(void)
|
||||
{
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
SCR1 = 0; /* disable transmitter (& receiver) */
|
||||
SCR1 = (SCI_TE|SCI_RE); /* re-enable transmitter & receiver */
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for SCI init completion (!) */
|
||||
serial_mode = SER_POLL_READ;
|
||||
TDR1 = 0xFF; /* send do-nothing while reading */
|
||||
}
|
||||
|
||||
static void write_transfer(const unsigned char *buf, int len)
|
||||
{
|
||||
const unsigned char *buf_end = buf + len;
|
||||
register unsigned char data;
|
||||
|
||||
if (serial_mode != SER_POLL_WRITE)
|
||||
{
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
SCR1 = 0; /* disable transmitter & receiver */
|
||||
SSR1 = 0; /* clear all flags */
|
||||
SCR1 = SCI_TE; /* enable transmitter only */
|
||||
serial_mode = SER_POLL_WRITE;
|
||||
}
|
||||
|
||||
while (buf < buf_end)
|
||||
{
|
||||
data = fliptable[(signed char)(*buf++)]; /* bitswap */
|
||||
while (!(SSR1 & SCI_TDRE)); /* wait for end of transfer */
|
||||
TDR1 = data; /* write byte */
|
||||
SSR1 = 0; /* start transmitting */
|
||||
}
|
||||
}
|
||||
|
||||
/* don't call this with len == 0 */
|
||||
static void read_transfer(unsigned char *buf, int len)
|
||||
{
|
||||
unsigned char *buf_end = buf + len - 1;
|
||||
register signed char data;
|
||||
|
||||
if (serial_mode != SER_POLL_READ)
|
||||
set_sci1_poll_read();
|
||||
|
||||
SSR1 = 0; /* start receiving first byte */
|
||||
while (buf < buf_end)
|
||||
{
|
||||
while (!(SSR1 & SCI_RDRF)); /* wait for data */
|
||||
data = RDR1; /* read byte */
|
||||
SSR1 = 0; /* start receiving */
|
||||
*buf++ = fliptable[data]; /* bitswap */
|
||||
}
|
||||
while (!(SSR1 & SCI_RDRF)); /* wait for last byte */
|
||||
*buf = fliptable[(signed char)(RDR1)]; /* read & bitswap */
|
||||
}
|
||||
|
||||
/* returns 0xFF on timeout, timeout is in bytes */
|
||||
static unsigned char poll_byte(long timeout)
|
||||
{
|
||||
long i;
|
||||
unsigned char data = 0; /* stop the compiler complaining */
|
||||
|
||||
if (serial_mode != SER_POLL_READ)
|
||||
set_sci1_poll_read();
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
SSR1 = 0; /* start receiving */
|
||||
while (!(SSR1 & SCI_RDRF)); /* wait for data */
|
||||
data = RDR1; /* read byte */
|
||||
} while ((data == 0xFF) && (++i < timeout));
|
||||
|
||||
return fliptable[(signed char)data];
|
||||
}
|
||||
|
||||
/* returns 0 on timeout, timeout is in bytes */
|
||||
static unsigned char poll_busy(long timeout)
|
||||
{
|
||||
long i;
|
||||
unsigned char data, dummy;
|
||||
|
||||
if (serial_mode != SER_POLL_READ)
|
||||
set_sci1_poll_read();
|
||||
|
||||
/* get data response */
|
||||
SSR1 = 0; /* start receiving */
|
||||
while (!(SSR1 & SCI_RDRF)); /* wait for data */
|
||||
data = fliptable[(signed char)(RDR1)]; /* read byte */
|
||||
|
||||
/* wait until the card is ready again */
|
||||
i = 0;
|
||||
do {
|
||||
SSR1 = 0; /* start receiving */
|
||||
while (!(SSR1 & SCI_RDRF)); /* wait for data */
|
||||
dummy = RDR1; /* read byte */
|
||||
} while ((dummy != 0xFF) && (++i < timeout));
|
||||
|
||||
return (dummy == 0xFF) ? data : 0;
|
||||
}
|
||||
|
||||
/* Send MMC command and get response. Returns R1 byte directly.
|
||||
* Returns further R2 or R3 bytes in *data (can be NULL for other commands) */
|
||||
static unsigned char send_cmd(int cmd, unsigned long parameter, void *data)
|
||||
{
|
||||
static struct {
|
||||
unsigned char cmd;
|
||||
unsigned long parameter;
|
||||
const unsigned char crc7; /* fixed, valid for CMD0 only */
|
||||
const unsigned char trailer;
|
||||
} __attribute__((packed)) command = {0x40, 0, 0x95, 0xFF};
|
||||
|
||||
unsigned char ret;
|
||||
|
||||
command.cmd = cmd;
|
||||
command.parameter = htobe32(parameter);
|
||||
|
||||
write_transfer((unsigned char *)&command, sizeof(command));
|
||||
|
||||
ret = poll_byte(20);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CMD_SEND_CSD: /* R1 response, leave open */
|
||||
case CMD_SEND_CID:
|
||||
case CMD_READ_SINGLE_BLOCK:
|
||||
case CMD_READ_MULTIPLE_BLOCK:
|
||||
return ret;
|
||||
|
||||
case CMD_SEND_STATUS: /* R2 response, close with dummy */
|
||||
read_transfer(data, 1);
|
||||
break;
|
||||
|
||||
case CMD_READ_OCR: /* R3 response, close with dummy */
|
||||
read_transfer(data, 4);
|
||||
break;
|
||||
|
||||
default: /* R1 response, close with dummy */
|
||||
break; /* also catches block writes */
|
||||
}
|
||||
write_transfer(dummy, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive CID/ CSD data (16 bytes) */
|
||||
static int receive_cxd(unsigned char *buf)
|
||||
{
|
||||
if (poll_byte(20) != DT_START_BLOCK)
|
||||
{
|
||||
write_transfer(dummy, 1);
|
||||
return -1; /* not start of data */
|
||||
}
|
||||
|
||||
read_transfer(buf, 16);
|
||||
write_transfer(dummy, 3); /* 2 bytes dontcare crc + 1 byte trailer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int initialize_card(int card_no)
|
||||
{
|
||||
int rc, i;
|
||||
int blk_exp, ts_exp, taac_exp;
|
||||
tCardInfo *card = &card_info[card_no];
|
||||
|
||||
static const char mantissa[] = { /* *10 */
|
||||
0, 10, 12, 13, 15, 20, 25, 30,
|
||||
35, 40, 45, 50, 55, 60, 70, 80
|
||||
};
|
||||
static const int exponent[] = { /* use varies */
|
||||
1, 10, 100, 1000, 10000, 100000, 1000000,
|
||||
10000000, 100000000, 1000000000
|
||||
};
|
||||
|
||||
if (card_no == 1)
|
||||
mmc_status = MMC_TOUCHED;
|
||||
|
||||
/* switch to SPI mode */
|
||||
if (send_cmd(CMD_GO_IDLE_STATE, 0, NULL) != 0x01)
|
||||
return -1; /* error or no response */
|
||||
|
||||
/* initialize card */
|
||||
for (i = HZ;;) /* try for 1 second*/
|
||||
{
|
||||
sleep(1);
|
||||
if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0)
|
||||
break;
|
||||
if (--i <= 0)
|
||||
return -2; /* timeout */
|
||||
}
|
||||
|
||||
/* get OCR register */
|
||||
if (send_cmd(CMD_READ_OCR, 0, &card->ocr))
|
||||
return -3;
|
||||
card->ocr = betoh32(card->ocr); /* no-op on big endian */
|
||||
|
||||
/* check voltage */
|
||||
if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */
|
||||
return -4;
|
||||
|
||||
/* get CSD register */
|
||||
if (send_cmd(CMD_SEND_CSD, 0, NULL))
|
||||
return -5;
|
||||
rc = receive_cxd((unsigned char*)card->csd);
|
||||
if (rc)
|
||||
return rc * 10 - 5;
|
||||
|
||||
blk_exp = card_extract_bits(card->csd, 83, 4);
|
||||
if (blk_exp < 9) /* block size < 512 bytes not supported */
|
||||
return -6;
|
||||
|
||||
card->numblocks = (card_extract_bits(card->csd, 73, 12) + 1)
|
||||
<< (card_extract_bits(card->csd, 49, 3) + 2 + blk_exp - 9);
|
||||
card->blocksize = BLOCK_SIZE;
|
||||
|
||||
/* max transmission speed, clock divider */
|
||||
ts_exp = card_extract_bits(card->csd, 98, 3);
|
||||
ts_exp = (ts_exp > 3) ? 3 : ts_exp;
|
||||
card->speed = mantissa[card_extract_bits(card->csd, 102, 4)]
|
||||
* exponent[ts_exp + 4];
|
||||
card->bitrate_register = (FREQ/4-1) / card->speed;
|
||||
|
||||
/* NSAC, TAAC, read timeout */
|
||||
card->nsac = 100 * card_extract_bits(card->csd, 111, 8);
|
||||
card->taac = mantissa[card_extract_bits(card->csd, 118, 4)];
|
||||
taac_exp = card_extract_bits(card->csd, 114, 3);
|
||||
card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1)
|
||||
* card->taac / exponent[9 - taac_exp]
|
||||
+ (10 * card->nsac));
|
||||
card->read_timeout /= 8; /* clocks -> bytes */
|
||||
card->taac = card->taac * exponent[taac_exp] / 10;
|
||||
|
||||
/* r2w_factor, write timeout */
|
||||
card->r2w_factor = BIT_N(card_extract_bits(card->csd, 28, 3));
|
||||
card->write_timeout = card->read_timeout * card->r2w_factor;
|
||||
|
||||
if (card->r2w_factor > 32) /* Such cards often need extra read delay */
|
||||
card->read_timeout *= 4;
|
||||
|
||||
/* switch to full speed */
|
||||
setup_sci1(card->bitrate_register);
|
||||
|
||||
/* always use 512 byte blocks */
|
||||
if (send_cmd(CMD_SET_BLOCKLEN, BLOCK_SIZE, NULL))
|
||||
return -7;
|
||||
|
||||
/* get CID register */
|
||||
if (send_cmd(CMD_SEND_CID, 0, NULL))
|
||||
return -8;
|
||||
rc = receive_cxd((unsigned char*)card->cid);
|
||||
if (rc)
|
||||
return rc * 10 - 8;
|
||||
|
||||
card->initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tCardInfo *mmc_card_info(int card_no)
|
||||
{
|
||||
tCardInfo *card = &card_info[card_no];
|
||||
|
||||
if (!card->initialized && ((card_no == 0) || mmc_detect()))
|
||||
{
|
||||
select_card(card_no);
|
||||
deselect_card();
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
/* Receive one block with DMA and bitswap it (chasing bitswap). */
|
||||
static int receive_block(unsigned char *inbuf, long timeout)
|
||||
{
|
||||
unsigned long buf_end;
|
||||
|
||||
if (poll_byte(timeout) != DT_START_BLOCK)
|
||||
{
|
||||
write_transfer(dummy, 1);
|
||||
return -1; /* not start of data */
|
||||
}
|
||||
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
|
||||
SCR1 = 0; /* disable serial */
|
||||
SSR1 = 0; /* clear all flags */
|
||||
|
||||
/* setup DMA channel 0 */
|
||||
CHCR0 = 0; /* disable */
|
||||
SAR0 = RDR1_ADDR;
|
||||
DAR0 = (unsigned long) inbuf;
|
||||
DTCR0 = BLOCK_SIZE;
|
||||
CHCR0 = 0x4601; /* fixed source address, RXI1, enable */
|
||||
DMAOR = 0x0001;
|
||||
SCR1 = (SCI_RE|SCI_RIE); /* kick off DMA */
|
||||
|
||||
/* DMA receives 2 bytes more than DTCR2, but the last 2 bytes are not
|
||||
* stored. The first extra byte is available from RDR1 after the DMA ends,
|
||||
* the second one is lost because of the SCI overrun. However, this
|
||||
* behaviour conveniently discards the crc. */
|
||||
|
||||
yield(); /* be nice */
|
||||
|
||||
/* Bitswap received data, chasing the DMA pointer */
|
||||
buf_end = (unsigned long)inbuf + BLOCK_SIZE;
|
||||
do
|
||||
{
|
||||
/* Call bitswap whenever (a multiple of) 8 bytes are
|
||||
* available (value optimised by experimentation). */
|
||||
int swap_now = (DAR0 - (unsigned long)inbuf) & ~0x00000007;
|
||||
if (swap_now)
|
||||
{
|
||||
bitswap(inbuf, swap_now);
|
||||
inbuf += swap_now;
|
||||
}
|
||||
}
|
||||
while ((unsigned long)inbuf < buf_end);
|
||||
|
||||
while (!(CHCR0 & 0x0002)); /* wait for end of DMA */
|
||||
while (!(SSR1 & SCI_ORER)); /* wait for the trailing bytes */
|
||||
SCR1 = 0;
|
||||
serial_mode = SER_DISABLED;
|
||||
|
||||
write_transfer(dummy, 1); /* send trailer */
|
||||
last_disk_activity = current_tick;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Prepare a block for sending by copying it to the next write buffer
|
||||
* and bitswapping it. */
|
||||
static void send_block_prepare(void)
|
||||
{
|
||||
unsigned char *dest;
|
||||
|
||||
current_buffer ^= 1; /* toggle buffer */
|
||||
dest = write_buffer[current_buffer] + 2;
|
||||
|
||||
memcpy(dest, send_block_addr, BLOCK_SIZE);
|
||||
bitswap(dest, BLOCK_SIZE);
|
||||
|
||||
send_block_addr += BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Send one block with DMA from the current write buffer, possibly preparing
|
||||
* the next block within the next write buffer in the background. */
|
||||
static int send_block_send(unsigned char start_token, long timeout,
|
||||
bool prepare_next)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned char *curbuf = write_buffer[current_buffer];
|
||||
|
||||
curbuf[1] = fliptable[(signed char)start_token];
|
||||
*(unsigned short *)(curbuf + BLOCK_SIZE + 2) = 0xFFFF;
|
||||
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
|
||||
SCR1 = 0; /* disable serial */
|
||||
SSR1 = 0; /* clear all flags */
|
||||
|
||||
/* setup DMA channel 0 */
|
||||
CHCR0 = 0; /* disable */
|
||||
SAR0 = (unsigned long)(curbuf + 1);
|
||||
DAR0 = TDR1_ADDR;
|
||||
DTCR0 = BLOCK_SIZE + 3; /* start token + block + dummy crc */
|
||||
CHCR0 = 0x1701; /* fixed dest. address, TXI1, enable */
|
||||
DMAOR = 0x0001;
|
||||
SCR1 = (SCI_TE|SCI_TIE); /* kick off DMA */
|
||||
|
||||
if (prepare_next)
|
||||
send_block_prepare();
|
||||
yield(); /* be nice */
|
||||
|
||||
while (!(CHCR0 & 0x0002)); /* wait for end of DMA */
|
||||
while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */
|
||||
SCR1 = 0;
|
||||
serial_mode = SER_DISABLED;
|
||||
|
||||
if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */
|
||||
rc = -1;
|
||||
|
||||
write_transfer(dummy, 1);
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mmc_read_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
int incount,
|
||||
void* inbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
int lastblock = 0;
|
||||
unsigned long end_block;
|
||||
tCardInfo *card;
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
int drive = current_card;
|
||||
#endif
|
||||
|
||||
card = &card_info[drive];
|
||||
rc = select_card(drive);
|
||||
if (rc)
|
||||
{
|
||||
rc = rc * 10 - 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
end_block = start + incount;
|
||||
if (end_block > card->numblocks)
|
||||
{
|
||||
rc = -2;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Some cards don't like reading the very last block with
|
||||
* CMD_READ_MULTIPLE_BLOCK, so make sure this block is always
|
||||
* read with CMD_READ_SINGLE_BLOCK. */
|
||||
if (end_block == card->numblocks)
|
||||
lastblock = 1;
|
||||
|
||||
if (incount > 1)
|
||||
{
|
||||
/* MMC4.2: make multiplication conditional */
|
||||
if (send_cmd(CMD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL))
|
||||
{
|
||||
rc = -3;
|
||||
goto error;
|
||||
}
|
||||
while (--incount >= lastblock)
|
||||
{
|
||||
rc = receive_block(inbuf, card->read_timeout);
|
||||
if (rc)
|
||||
{
|
||||
/* If an error occurs during multiple block reading, the
|
||||
* host still needs to send CMD_STOP_TRANSMISSION */
|
||||
send_cmd(CMD_STOP_TRANSMISSION, 0, NULL);
|
||||
rc = rc * 10 - 4;
|
||||
goto error;
|
||||
}
|
||||
inbuf += BLOCK_SIZE;
|
||||
start++;
|
||||
/* ^^ necessary for the abovementioned last block special case */
|
||||
}
|
||||
if (send_cmd(CMD_STOP_TRANSMISSION, 0, NULL))
|
||||
{
|
||||
rc = -5;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (incount > 0)
|
||||
{
|
||||
/* MMC4.2: make multiplication conditional */
|
||||
if (send_cmd(CMD_READ_SINGLE_BLOCK, start * BLOCK_SIZE, NULL))
|
||||
{
|
||||
rc = -6;
|
||||
goto error;
|
||||
}
|
||||
rc = receive_block(inbuf, card->read_timeout);
|
||||
if (rc)
|
||||
{
|
||||
rc = rc * 10 - 7;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
deselect_card();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mmc_write_sectors(IF_MD(int drive,)
|
||||
unsigned long start,
|
||||
int count,
|
||||
const void* buf)
|
||||
{
|
||||
int rc = 0;
|
||||
int write_cmd;
|
||||
unsigned char start_token;
|
||||
tCardInfo *card;
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
int drive = current_card;
|
||||
#endif
|
||||
|
||||
card = &card_info[drive];
|
||||
rc = select_card(drive);
|
||||
if (rc)
|
||||
{
|
||||
rc = rc * 10 - 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (start + count > card->numblocks)
|
||||
panicf("Writing past end of card");
|
||||
|
||||
send_block_addr = buf;
|
||||
send_block_prepare();
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
write_cmd = CMD_WRITE_MULTIPLE_BLOCK;
|
||||
start_token = DT_START_WRITE_MULTIPLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_cmd = CMD_WRITE_BLOCK;
|
||||
start_token = DT_START_BLOCK;
|
||||
}
|
||||
/* MMC4.2: make multiplication conditional */
|
||||
if (send_cmd(write_cmd, start * BLOCK_SIZE, NULL))
|
||||
{
|
||||
rc = -2;
|
||||
goto error;
|
||||
}
|
||||
while (--count >= 0)
|
||||
{
|
||||
rc = send_block_send(start_token, card->write_timeout, count > 0);
|
||||
if (rc)
|
||||
{
|
||||
rc = rc * 10 - 3;
|
||||
break;
|
||||
/* If an error occurs during multiple block writing,
|
||||
* the STOP_TRAN token still needs to be sent. */
|
||||
}
|
||||
}
|
||||
if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK)
|
||||
{
|
||||
static const unsigned char stop_tran = DT_STOP_TRAN;
|
||||
write_transfer(&stop_tran, 1);
|
||||
poll_busy(card->write_timeout);
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
deselect_card();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool mmc_disk_is_active(void)
|
||||
{
|
||||
/* this is correct unless early return from write gets implemented */
|
||||
return mutex_test(&mmc_mutex);
|
||||
}
|
||||
|
||||
bool mmc_detect(void)
|
||||
{
|
||||
return (adc_read(ADC_MMC_SWITCH) < 0x200);
|
||||
}
|
||||
|
||||
bool mmc_touched(void)
|
||||
{
|
||||
if (mmc_status == MMC_UNKNOWN) /* try to detect */
|
||||
{
|
||||
mutex_lock(&mmc_mutex);
|
||||
setup_sci1(7); /* safe value */
|
||||
and_b(~0x02, &PADRH); /* assert CS */
|
||||
if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0xFF)
|
||||
mmc_status = MMC_UNTOUCHED;
|
||||
else
|
||||
mmc_status = MMC_TOUCHED;
|
||||
|
||||
deselect_card();
|
||||
}
|
||||
return mmc_status == MMC_TOUCHED;
|
||||
}
|
||||
|
||||
bool mmc_usb_active(int delayticks)
|
||||
{
|
||||
/* reading "inactive" is delayed by user-supplied monoflop value */
|
||||
return (usb_activity ||
|
||||
TIME_BEFORE(current_tick, last_usb_activity + delayticks));
|
||||
}
|
||||
|
||||
static void mmc_tick(void)
|
||||
{
|
||||
bool current_status;
|
||||
|
||||
if (new_mmc_circuit)
|
||||
/* USB bridge activity is 0 on idle, ~527 on active */
|
||||
current_status = adc_read(ADC_USB_ACTIVE) > 0x100;
|
||||
else
|
||||
current_status = adc_read(ADC_USB_ACTIVE) < 0x190;
|
||||
|
||||
if (!current_status && usb_activity)
|
||||
last_usb_activity = current_tick;
|
||||
usb_activity = current_status;
|
||||
|
||||
current_status = mmc_detect();
|
||||
/* Only report when the status has changed */
|
||||
if (current_status != last_mmc_status)
|
||||
{
|
||||
last_mmc_status = current_status;
|
||||
countdown = HZ/3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Count down until it gets negative */
|
||||
if (countdown >= 0)
|
||||
countdown--;
|
||||
|
||||
if (countdown == 0)
|
||||
{
|
||||
if (current_status)
|
||||
{
|
||||
queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1);
|
||||
mmc_status = MMC_UNTOUCHED;
|
||||
card_info[1].initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mmc_enable(bool on)
|
||||
{
|
||||
mutex_lock(&mmc_mutex);
|
||||
enable_controller(on);
|
||||
mutex_unlock(&mmc_mutex);
|
||||
}
|
||||
|
||||
int mmc_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!initialized)
|
||||
mutex_init(&mmc_mutex);
|
||||
|
||||
mutex_lock(&mmc_mutex);
|
||||
led(false);
|
||||
|
||||
last_mmc_status = mmc_detect();
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
/* Use MMC if inserted, internal flash otherwise */
|
||||
current_card = last_mmc_status ? 1 : 0;
|
||||
#endif
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
if (!last_mmc_status)
|
||||
mmc_status = MMC_UNTOUCHED;
|
||||
|
||||
/* Port setup */
|
||||
PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12
|
||||
* (clk gate), PA10 (flash CS), PA9 (MMC CS) */
|
||||
PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */
|
||||
PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
|
||||
PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
|
||||
|
||||
PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */
|
||||
PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */
|
||||
PBIOR |= 0x2000; /* SCK1 output */
|
||||
PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
|
||||
|
||||
IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
|
||||
|
||||
new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
|
||||
tick_add_task(mmc_tick);
|
||||
initialized = true;
|
||||
}
|
||||
enable_controller(true);
|
||||
|
||||
mutex_unlock(&mmc_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
long mmc_last_disk_activity(void)
|
||||
{
|
||||
return last_disk_activity;
|
||||
}
|
||||
|
||||
#ifdef STORAGE_GET_INFO
|
||||
void mmc_get_info(IF_MD(int drive,) struct storage_info *info)
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
const int drive=0;
|
||||
#endif
|
||||
info->sector_size=card_info[drive].blocksize;
|
||||
info->num_sectors=card_info[drive].numblocks;
|
||||
info->vendor="Rockbox";
|
||||
if(drive==0)
|
||||
{
|
||||
info->product="Internal Storage";
|
||||
}
|
||||
else
|
||||
{
|
||||
info->product="MMC Card Slot";
|
||||
}
|
||||
info->revision="0.00";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
bool mmc_removable(IF_MD_NONVOID(int drive))
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
const int drive=0;
|
||||
#endif
|
||||
return (drive==1);
|
||||
}
|
||||
|
||||
bool mmc_present(IF_MD_NONVOID(int drive))
|
||||
{
|
||||
#ifndef HAVE_MULTIDRIVE
|
||||
const int drive=0;
|
||||
#endif
|
||||
if(drive==0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mmc_detect();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void mmc_spin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mmc_spindown(int seconds)
|
||||
{
|
||||
(void)seconds;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STORAGE_MULTI
|
||||
int mmc_num_drives(int first_drive)
|
||||
{
|
||||
mmc_first_drive = first_drive;
|
||||
return MMC_NUM_DRIVES;
|
||||
}
|
||||
#endif /* CONFIG_STORAGE_MULTI */
|
||||
|
||||
int mmc_event(long id, intptr_t data)
|
||||
{
|
||||
return storage_event_default_handler(id, data, last_disk_activity,
|
||||
STORAGE_MMC);
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef BACKLIGHT_TARGET_H
|
||||
#define BACKLIGHT_TARGET_H
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef HAVE_BACKLIGHT
|
||||
/* A stock Ondio has no backlight, it needs a hardware mod. */
|
||||
|
||||
static inline bool backlight_hw_init(void)
|
||||
{
|
||||
PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */
|
||||
or_b(0x40, &PADRH); /* drive it high */
|
||||
or_b(0x40, &PAIORH); /* ..and output */
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void backlight_hw_on(void)
|
||||
{
|
||||
or_b(0x40, &PADRH); /* drive it high */
|
||||
}
|
||||
|
||||
static inline void backlight_hw_off(void)
|
||||
{
|
||||
and_b(~0x40, &PADRH); /* drive it low */
|
||||
}
|
||||
#endif /* HAVE_BACKLIGHT */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
#include "backlight.h"
|
||||
#include "adc.h"
|
||||
|
||||
/*
|
||||
Ondio hardware button hookup
|
||||
============================
|
||||
|
||||
LEFT, RIGHT, UP, DOWN: connected to AN4 through a resistor network
|
||||
|
||||
The voltage on AN4 depends on which keys (or key combo) is pressed
|
||||
|
||||
OPTION: AN2, high active (assigned as MENU)
|
||||
ON/OFF: AN3, low active (assigned as OFF)
|
||||
*/
|
||||
|
||||
void button_init_device(void)
|
||||
{
|
||||
}
|
||||
|
||||
int button_read_device(void)
|
||||
{
|
||||
int btn = BUTTON_NONE;
|
||||
int data;
|
||||
|
||||
/* Check the 4 direction keys */
|
||||
data = adc_read(ADC_BUTTON_ROW1);
|
||||
if (data >= 165)
|
||||
{
|
||||
if (data >= 585)
|
||||
if (data >= 755)
|
||||
btn = BUTTON_LEFT;
|
||||
else
|
||||
btn = BUTTON_RIGHT;
|
||||
else
|
||||
if (data >= 415)
|
||||
btn = BUTTON_UP;
|
||||
else
|
||||
btn = BUTTON_DOWN;
|
||||
}
|
||||
|
||||
if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */
|
||||
btn |= BUTTON_MENU;
|
||||
if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */
|
||||
btn |= BUTTON_OFF;
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _BUTTON_TARGET_H_
|
||||
#define _BUTTON_TARGET_H_
|
||||
|
||||
#define BUTTON_OFF 0x00000001
|
||||
#define BUTTON_MENU 0x00000002
|
||||
|
||||
#define BUTTON_LEFT 0x00000004
|
||||
#define BUTTON_RIGHT 0x00000008
|
||||
#define BUTTON_UP 0x00000010
|
||||
#define BUTTON_DOWN 0x00000020
|
||||
|
||||
#define BUTTON_MAIN (BUTTON_OFF|BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT\
|
||||
|BUTTON_UP|BUTTON_DOWN)
|
||||
|
||||
#define POWEROFF_BUTTON BUTTON_OFF
|
||||
#define POWEROFF_COUNT 10
|
||||
|
||||
#endif /* _BUTTON_TARGET_H_ */
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
* Physical interface of the Philips TEA5767 in Archos Ondio
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel.h"
|
||||
#include "logf.h"
|
||||
#include "system.h"
|
||||
#include "fmradio_i2c.h"
|
||||
|
||||
#if (CONFIG_TUNER & TEA5767)
|
||||
|
||||
/* cute little functions, atomic read-modify-write */
|
||||
/* SDA is PB4 */
|
||||
#define SDA_LO and_b(~0x10, &PBDRL)
|
||||
#define SDA_HI or_b(0x10, &PBDRL)
|
||||
#define SDA_INPUT and_b(~0x10, &PBIORL)
|
||||
#define SDA_OUTPUT or_b(0x10, &PBIORL)
|
||||
#define SDA (PBDR & 0x0010)
|
||||
|
||||
/* SCL is PB1 */
|
||||
#define SCL_INPUT and_b(~0x02, &PBIORL)
|
||||
#define SCL_OUTPUT or_b(0x02, &PBIORL)
|
||||
#define SCL_LO and_b(~0x02, &PBDRL)
|
||||
#define SCL_HI or_b(0x02, &PBDRL)
|
||||
#define SCL (PBDR & 0x0002)
|
||||
|
||||
/* arbitrary delay loop */
|
||||
#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
|
||||
|
||||
static void fmradio_i2c_start(void)
|
||||
{
|
||||
SDA_OUTPUT;
|
||||
SDA_HI;
|
||||
SCL_HI;
|
||||
SDA_LO;
|
||||
DELAY;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
static void fmradio_i2c_stop(void)
|
||||
{
|
||||
SDA_LO;
|
||||
SCL_HI;
|
||||
DELAY;
|
||||
SDA_HI;
|
||||
}
|
||||
|
||||
|
||||
static void fmradio_i2c_ack(bool nack)
|
||||
{
|
||||
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
||||
before it can receive the acknowledge. Therefore it forces the clock
|
||||
low until it is ready. We need to poll the clock line until it goes
|
||||
high before we release the ack. */
|
||||
|
||||
SCL_LO; /* Set the clock low */
|
||||
|
||||
if (nack)
|
||||
SDA_HI;
|
||||
else
|
||||
SDA_LO;
|
||||
|
||||
SCL_INPUT; /* Set the clock to input */
|
||||
while(!SCL) /* and wait for the slave to release it */
|
||||
sleep(0);
|
||||
|
||||
DELAY;
|
||||
SCL_OUTPUT;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
static int fmradio_i2c_getack(void)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
||||
before it can send the acknowledge. Therefore it forces the clock
|
||||
low until it is ready. We need to poll the clock line until it goes
|
||||
high before we read the ack. */
|
||||
|
||||
SDA_INPUT; /* And set to input */
|
||||
SCL_INPUT; /* Set the clock to input */
|
||||
while(!SCL) /* and wait for the slave to release it */
|
||||
sleep(0);
|
||||
|
||||
if (SDA)
|
||||
/* ack failed */
|
||||
ret = 0;
|
||||
|
||||
SCL_OUTPUT;
|
||||
SCL_LO;
|
||||
SDA_HI;
|
||||
SDA_OUTPUT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fmradio_i2c_outb(unsigned char byte)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* clock out each bit, MSB first */
|
||||
for ( i=0x80; i; i>>=1 ) {
|
||||
if ( i & byte )
|
||||
{
|
||||
SDA_HI;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDA_LO;
|
||||
}
|
||||
SCL_HI;
|
||||
SCL_LO;
|
||||
}
|
||||
|
||||
SDA_HI;
|
||||
}
|
||||
|
||||
static unsigned char fmradio_i2c_inb(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char byte = 0;
|
||||
|
||||
/* clock in each bit, MSB first */
|
||||
for ( i=0x80; i; i>>=1 ) {
|
||||
SDA_INPUT; /* And set to input */
|
||||
SCL_HI;
|
||||
if ( SDA )
|
||||
byte |= i;
|
||||
SCL_LO;
|
||||
SDA_OUTPUT;
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
|
||||
{
|
||||
int i,x=0;
|
||||
|
||||
fmradio_i2c_start();
|
||||
fmradio_i2c_outb(address & 0xfe);
|
||||
if (fmradio_i2c_getack())
|
||||
{
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
fmradio_i2c_outb(buf[i]);
|
||||
if (!fmradio_i2c_getack())
|
||||
{
|
||||
x=-2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logf("fmradio_i2c_write() - no ack\n");
|
||||
x=-1;
|
||||
}
|
||||
fmradio_i2c_stop();
|
||||
return x;
|
||||
}
|
||||
|
||||
int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
|
||||
{
|
||||
int i,x=0;
|
||||
|
||||
fmradio_i2c_start();
|
||||
fmradio_i2c_outb(address | 1);
|
||||
if (fmradio_i2c_getack()) {
|
||||
for (i=count; i>0; i--)
|
||||
{
|
||||
*buf++ = fmradio_i2c_inb();
|
||||
fmradio_i2c_ack(i == 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
x=-1;
|
||||
fmradio_i2c_stop();
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include <stdbool.h>
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "usb.h"
|
||||
#include "backlight-target.h"
|
||||
|
||||
#if CONFIG_TUNER
|
||||
|
||||
static bool powered = false;
|
||||
|
||||
bool tuner_power(bool status)
|
||||
{
|
||||
bool old_status = powered;
|
||||
|
||||
powered = status;
|
||||
if (status)
|
||||
{
|
||||
and_b(~0x04, &PADRL); /* drive PA2 low for tuner enable */
|
||||
sleep(1); /* let the voltage settle */
|
||||
}
|
||||
else
|
||||
or_b(0x04, &PADRL); /* drive PA2 high for tuner disable */
|
||||
return old_status;
|
||||
}
|
||||
|
||||
#endif /* #if CONFIG_TUNER */
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
PBCR2 &= ~0x0c00; /* GPIO for PB5 */
|
||||
or_b(0x20, &PBIORL);
|
||||
or_b(0x20, &PBDRL); /* hold power */
|
||||
#ifndef HAVE_BACKLIGHT
|
||||
/* Disable backlight on backlight-modded Ondios when running
|
||||
* a standard build (always on otherwise). */
|
||||
PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */
|
||||
and_b(~0x40, &PADRH); /* drive it low */
|
||||
or_b(0x40, &PAIORH); /* ..and output */
|
||||
#endif
|
||||
PACR2 &= ~0x0030; /* GPIO for PA2 */
|
||||
or_b(0x04, &PADRL); /* drive PA2 high for tuner disable */
|
||||
or_b(0x04, &PAIORL); /* output for PA2 */
|
||||
}
|
||||
|
||||
void power_off(void)
|
||||
{
|
||||
disable_irq();
|
||||
#ifdef HAVE_BACKLIGHT
|
||||
/* Switch off the light on backlight-modded Ondios */
|
||||
backlight_hw_off();
|
||||
#endif
|
||||
and_b(~0x20, &PBDRL);
|
||||
or_b(0x20, &PBIORL);
|
||||
while(1);
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "adc.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
3100, 3450
|
||||
};
|
||||
|
||||
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
2700, 2800
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% */
|
||||
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
|
||||
{
|
||||
/* measured values */
|
||||
{ 2800, 3250, 3410, 3530, 3640, 3740, 3850, 3950, 4090, 4270, 4750 }, /* Alkaline */
|
||||
{ 3100, 3550, 3630, 3690, 3720, 3740, 3760, 3780, 3800, 3860, 4050 } /* NiMH */
|
||||
};
|
||||
|
||||
#define BATTERY_SCALE_FACTOR 4849 /* average from 3 Ondios */
|
||||
/* full-scale ADC readout (2^10) in millivolt */
|
||||
|
||||
/* Returns battery voltage from ADC [millivolts] */
|
||||
int _battery_voltage(void)
|
||||
{
|
||||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include "adc.h"
|
||||
#include "ata_mmc.h"
|
||||
#include "cpu.h"
|
||||
#include "hwcompat.h"
|
||||
#include "system.h"
|
||||
#include "usb.h"
|
||||
|
||||
int usb_detect(void)
|
||||
{
|
||||
return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED;
|
||||
}
|
||||
|
||||
void usb_enable(bool on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
mmc_enable_int_flash_clock(!mmc_detect());
|
||||
|
||||
if (!(HW_MASK & MMC_CLOCK_POLARITY))
|
||||
and_b(~0x20, &PBDRH); /* old circuit needs SCK1 = low while on USB */
|
||||
or_b(0x20, &PADRL); /* enable USB */
|
||||
and_b(~0x08, &PADRL); /* assert card detect */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(HW_MASK & MMC_CLOCK_POLARITY))
|
||||
or_b(0x20, &PBDRH); /* reset SCK1 = high for old circuit */
|
||||
and_b(~0x20, &PADRL); /* disable USB */
|
||||
or_b(0x08, &PADRL); /* deassert card detect */
|
||||
}
|
||||
}
|
||||
|
||||
void usb_init_device(void)
|
||||
{
|
||||
PACR2 &= ~0x04C0; /* use PA3 (card detect) and PA5 (USB enabled) as GPIO */
|
||||
and_b(~0x20, &PADRL); /* disable USB */
|
||||
or_b(0x08, &PADRL); /* deassert card detect */
|
||||
or_b(0x28, &PAIORL); /* output for USB enable and card detect */
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _ADC_TARGET_H_
|
||||
#define _ADC_TARGET_H_
|
||||
|
||||
#define NUM_ADC_CHANNELS 8
|
||||
|
||||
#define ADC_BUTTON_LEFT 0
|
||||
#define ADC_BUTTON_MENU 1
|
||||
#define ADC_BUTTON_RIGHT 2
|
||||
#define ADC_BUTTON_PLAY 3
|
||||
#define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */
|
||||
#define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */
|
||||
|
||||
#define EXT_SCALE_FACTOR 14800
|
||||
|
||||
#endif /* _ADC_TARGET_H_ */
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef BACKLIGHT_TARGET_H
|
||||
#define BACKLIGHT_TARGET_H
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
static inline bool backlight_hw_init(void)
|
||||
{
|
||||
PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */
|
||||
and_b(~0x40, &PADRH); /* drive and set low */
|
||||
or_b(0x40, &PAIORH); /* ..and output */
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void backlight_hw_on(void)
|
||||
{
|
||||
and_b(~0x40, &PADRH); /* drive and set low */
|
||||
or_b(0x40, &PAIORH);
|
||||
}
|
||||
|
||||
static inline void backlight_hw_off(void)
|
||||
{
|
||||
and_b(~0x40, &PAIORH); /* let it float (up) */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
#include "backlight.h"
|
||||
#include "adc.h"
|
||||
|
||||
/*
|
||||
Player hardware button hookup
|
||||
=============================
|
||||
|
||||
Player
|
||||
------
|
||||
LEFT: AN0
|
||||
MENU: AN1
|
||||
RIGHT: AN2
|
||||
PLAY: AN3
|
||||
|
||||
STOP: PA11
|
||||
ON: PA5
|
||||
|
||||
All buttons are low active
|
||||
*/
|
||||
|
||||
void button_init_device(void)
|
||||
{
|
||||
/* set PA5 and PA11 as input pins */
|
||||
PACR1 &= 0xff3f; /* PA11MD = 00 */
|
||||
PACR2 &= 0xfbff; /* PA5MD = 0 */
|
||||
PAIOR &= ~0x0820; /* Inputs */
|
||||
}
|
||||
|
||||
int button_read_device(void)
|
||||
{
|
||||
int btn = BUTTON_NONE;
|
||||
int data;
|
||||
|
||||
/* buttons are active low */
|
||||
if (adc_read(ADC_BUTTON_LEFT) < 0x180)
|
||||
btn = BUTTON_LEFT;
|
||||
if (adc_read(ADC_BUTTON_MENU) < 0x180)
|
||||
btn |= BUTTON_MENU;
|
||||
if (adc_read(ADC_BUTTON_RIGHT) < 0x180)
|
||||
btn |= BUTTON_RIGHT;
|
||||
if (adc_read(ADC_BUTTON_PLAY) < 0x180)
|
||||
btn |= BUTTON_PLAY;
|
||||
|
||||
/* check port A pins for ON and STOP */
|
||||
data = PADR;
|
||||
if ( !(data & 0x0020) )
|
||||
btn |= BUTTON_ON;
|
||||
if ( !(data & 0x0800) )
|
||||
btn |= BUTTON_STOP;
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _BUTTON_TARGET_H_
|
||||
#define _BUTTON_TARGET_H_
|
||||
|
||||
#define HAS_SERIAL_REMOTE
|
||||
|
||||
/* Main unit's buttons */
|
||||
#define BUTTON_ON 0x00000001
|
||||
#define BUTTON_STOP 0x00000002
|
||||
|
||||
#define BUTTON_LEFT 0x00000004
|
||||
#define BUTTON_RIGHT 0x00000008
|
||||
#define BUTTON_PLAY 0x00000010
|
||||
#define BUTTON_MENU 0x00000020
|
||||
|
||||
#define BUTTON_MAIN (BUTTON_ON|BUTTON_STOP|BUTTON_LEFT|BUTTON_RIGHT\
|
||||
|BUTTON_PLAY|BUTTON_MENU)
|
||||
|
||||
/* Remote control's buttons */
|
||||
#define BUTTON_RC_PLAY 0x00100000
|
||||
#define BUTTON_RC_STOP 0x00080000
|
||||
|
||||
#define BUTTON_RC_LEFT 0x00040000
|
||||
#define BUTTON_RC_RIGHT 0x00020000
|
||||
#define BUTTON_RC_VOL_UP 0x00010000
|
||||
#define BUTTON_RC_VOL_DOWN 0x00008000
|
||||
|
||||
#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
|
||||
|BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
|
||||
|BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
|
||||
|
||||
#endif /* _BUTTON_TARGET_H_ */
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hwcompat.h"
|
||||
|
||||
bool is_new_player(void)
|
||||
{
|
||||
return (ROM_VERSION > 449) || (ROM_VERSION == 116);
|
||||
}
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
* Based on the work of Alan Korr and Jörg Hohensohn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define LCDR (PBDR_ADDR+1)
|
||||
|
||||
#define LCD_DS 1 /* PB0 = 1 --- 0001 --- LCD-DS */
|
||||
#define LCD_CS 2 /* PB1 = 1 --- 0010 --- /LCD-CS */
|
||||
#define LCD_SD 4 /* PB2 = 1 --- 0100 --- LCD-SD */
|
||||
#define LCD_SC 8 /* PB3 = 1 --- 1000 --- LCD-SC */
|
||||
|
||||
/*
|
||||
* About /CS,DS,SC,SD
|
||||
* ------------------
|
||||
*
|
||||
* LCD on JBP and JBR uses a SPI protocol to receive orders (SDA and SCK lines)
|
||||
*
|
||||
* - /CS -> Chip Selection line :
|
||||
* 0 : LCD chipset is activated.
|
||||
* - DS -> Data Selection line, latched at the rising edge
|
||||
* of the 8th serial clock (*) :
|
||||
* 0 : instruction register,
|
||||
* 1 : data register;
|
||||
* - SC -> Serial Clock line (SDA).
|
||||
* - SD -> Serial Data line (SCK), latched at the rising edge
|
||||
* of each serial clock (*).
|
||||
*
|
||||
* _ _
|
||||
* /CS \ /
|
||||
* \______________________________________________________/
|
||||
* _____ ____ ____ ____ ____ ____ ____ ____ ____ _____
|
||||
* SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/
|
||||
* _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____
|
||||
*
|
||||
* _____ _ _ _ _ _ _ _ ________
|
||||
* SC \ * \ * \ * \ * \ * \ * \ * \ *
|
||||
* \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
||||
* _ _________________________________________________________
|
||||
* DS \/
|
||||
* _/\_________________________________________________________
|
||||
*
|
||||
*/
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
|
||||
.align 2
|
||||
.global _lcd_write_command
|
||||
.type _lcd_write_command,@function
|
||||
|
||||
/* Write a command byte to the lcd controller
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - command byte (int)
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1 - command byte (copied)
|
||||
* r2 - precalculated port value (CS, DS and SC low, SD high)
|
||||
* r3 - lcd port address
|
||||
* r5 - 1 (byte count for reuse of the loop in _lcd_write_data)
|
||||
*/
|
||||
|
||||
_lcd_write_command:
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
mov r4, r1 /* copy data byte to r1 */
|
||||
mov #0, r5 /* fake end address - stop after first iteration */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
or #(LCD_SD), r0 /* r0 |= LCD_SD */
|
||||
and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
|
||||
|
||||
bra .single_transfer /* jump into the transfer loop */
|
||||
mov r0, r2
|
||||
|
||||
|
||||
.align 2
|
||||
.global _lcd_write_command_e
|
||||
.type _lcd_write_command_e,@function
|
||||
|
||||
/* Write a command byte and a data byte to the lcd controller
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - command byte
|
||||
* r5 - data byte
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1 - command/data byte (copied)
|
||||
* r2 - precalculated port value (CS, DS and SC low, SD high)
|
||||
* r3 - lcd port address
|
||||
* r5 - fake end address
|
||||
* r6 - data byte (saved)
|
||||
* r7 - saved pr
|
||||
*/
|
||||
|
||||
_lcd_write_command_e:
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
mov r4, r1 /* copy data byte to r1 */
|
||||
mov r5, r6
|
||||
mov #0, r5 /* fake end address - stop after first iteration */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
or #(LCD_SD), r0 /* r0 |= LCD_SD */
|
||||
and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */
|
||||
|
||||
sts pr, r7
|
||||
bsr .single_transfer /* jump into the transfer loop */
|
||||
mov r0, r2
|
||||
|
||||
lds r7, pr
|
||||
mov r6, r1
|
||||
or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
|
||||
and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
||||
bra .single_transfer /* jump into the transfer loop */
|
||||
mov r0, r2
|
||||
|
||||
|
||||
.align 2
|
||||
.global _lcd_write_data
|
||||
.type _lcd_write_data,@function
|
||||
|
||||
|
||||
/* A high performance function to write data to the display,
|
||||
* one or multiple bytes.
|
||||
*
|
||||
* Arguments:
|
||||
* r4 - data address
|
||||
* r5 - byte count
|
||||
*
|
||||
* Register usage:
|
||||
* r0 - scratch
|
||||
* r1 - current data byte
|
||||
* r2 - precalculated port value (CS and SC low, DS and SD high)
|
||||
* r3 - lcd port address
|
||||
* r4 - current address
|
||||
* r5 - end address
|
||||
*/
|
||||
|
||||
_lcd_write_data:
|
||||
mov.l .lcdr, r3 /* put lcd data port address in r3 */
|
||||
add r4, r5 /* end address */
|
||||
|
||||
/* This code will fail if an interrupt changes the contents of PBDRL.
|
||||
* If so, we must disable the interrupt here. If disabling interrupts
|
||||
* for a long time (~9200 clks = ~830 µs for transferring 112 bytes on
|
||||
* recorders)is undesirable, the loop has to be rewritten to
|
||||
* disable/precalculate/transfer/enable for each iteration. However,
|
||||
* this would significantly decrease performance. */
|
||||
|
||||
mov.b @r3, r0 /* r0 = PBDRL */
|
||||
or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */
|
||||
and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */
|
||||
mov r0, r2
|
||||
|
||||
.align 2
|
||||
.multi_transfer:
|
||||
mov.b @r4+, r1 /* load data byte from memory */
|
||||
|
||||
.single_transfer:
|
||||
shll16 r1 /* shift data to most significant byte */
|
||||
shll8 r1
|
||||
|
||||
shll r1 /* shift the msb into carry */
|
||||
mov r2, r0 /* copy precalculated port value */
|
||||
bt 1f /* data bit = 1? */
|
||||
and #(~LCD_SD), r0 /* no: r0 &= ~LCD_SD */
|
||||
1:
|
||||
shll r1 /* next shift here for alignment */
|
||||
mov.b r0, @r3 /* set data to port */
|
||||
or #(LCD_SC), r0 /* rise SC (independent of SD level) */
|
||||
mov.b r0, @r3 /* set to port */
|
||||
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
shll r1
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
shll r1
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
mov r2, r0
|
||||
bt 1f
|
||||
and #(~LCD_SD), r0
|
||||
1:
|
||||
mov.b r0, @r3
|
||||
or #(LCD_SC), r0
|
||||
mov.b r0, @r3
|
||||
|
||||
cmp/hi r4, r5 /* some blocks left? */
|
||||
bt .multi_transfer
|
||||
|
||||
or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */
|
||||
rts
|
||||
mov.b r0, @r3
|
||||
|
||||
/* This is the place to reenable the interrupts, if we have disabled
|
||||
* them. See above. */
|
||||
|
||||
.align 2
|
||||
.lcdr:
|
||||
.long LCDR
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Based on the work of Alan Korr, Kjell Ericson and others
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "hwcompat.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd-charcell.h"
|
||||
|
||||
#define OLD_LCD_DDRAM ((char)0xB0) /* Display data (characters) */
|
||||
#define OLD_LCD_CGRAM ((char)0x80) /* Character generator (patterns) */
|
||||
#define OLD_LCD_ICONRAM ((char)0xE0)
|
||||
#define OLD_LCD_CONTRAST_SET ((char)0xA8)
|
||||
#define OLD_LCD_NOP ((char)0x00)
|
||||
#define OLD_LCD_SYSTEM_SET ((char)0x60)
|
||||
#define OLD_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x40)
|
||||
#define OLD_LCD_SET_POWER_CONTROL ((char)0x50)
|
||||
#define OLD_LCD_SET_DISPLAY_CONTROL ((char)0x30)
|
||||
|
||||
#define NEW_LCD_DDRAM ((char)0x80) /* Display data (characters) */
|
||||
#define NEW_LCD_CGRAM ((char)0xC0) /* Character generator (patterns) */
|
||||
#define NEW_LCD_ICONRAM ((char)0x40)
|
||||
#define NEW_LCD_CONTRAST_SET ((char)0x50)
|
||||
#define NEW_LCD_NOP ((char)0x00)
|
||||
#define NEW_LCD_FUNCTION_SET ((char)0x10)
|
||||
#define NEW_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x0c)
|
||||
#define NEW_LCD_SET_POWER_CONTROL_REG ((char)0x20)
|
||||
#define NEW_LCD_SET_DISPLAY_CONTROL ((char)0x28)
|
||||
#define NEW_LCD_SET_DOUBLE_HEIGHT ((char)0x08)
|
||||
|
||||
#define LCD_CURSOR(x,y) ((char)(lcd_ddram+((y)*16+(x))))
|
||||
#define LCD_ICON(i) ((char)(lcd_iconram+i))
|
||||
|
||||
static bool new_lcd;
|
||||
static char lcd_contrast_set;
|
||||
static char lcd_ddram;
|
||||
static char lcd_cgram;
|
||||
static char lcd_iconram;
|
||||
|
||||
/* hardware configuration */
|
||||
|
||||
int lcd_default_contrast(void)
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
void lcd_set_contrast(int val)
|
||||
{
|
||||
lcd_write_command_e(lcd_contrast_set, 31 - val);
|
||||
}
|
||||
|
||||
/* charcell specific */
|
||||
|
||||
void lcd_double_height(bool on)
|
||||
{
|
||||
if(new_lcd)
|
||||
lcd_write_command(on ? (NEW_LCD_SET_DOUBLE_HEIGHT|1)
|
||||
: NEW_LCD_SET_DOUBLE_HEIGHT);
|
||||
}
|
||||
|
||||
void lcd_icon(int icon, bool enable)
|
||||
{
|
||||
static const struct {
|
||||
char pos;
|
||||
char mask;
|
||||
} icontab[] = {
|
||||
{ 0, 0x02}, { 0, 0x08}, { 0, 0x04}, { 0, 0x10}, /* Battery */
|
||||
{ 2, 0x04}, /* USB */
|
||||
{ 3, 0x10}, /* Play */
|
||||
{ 4, 0x10}, /* Record */
|
||||
{ 5, 0x02}, /* Pause */
|
||||
{ 5, 0x10}, /* Audio */
|
||||
{ 6, 0x02}, /* Repeat */
|
||||
{ 7, 0x01}, /* 1 */
|
||||
{ 9, 0x04}, /* Volume */
|
||||
{ 9, 0x02}, { 9, 0x01}, {10, 0x08}, {10, 0x04}, {10, 0x01}, /* Vol 1-5 */
|
||||
{10, 0x10}, /* Param */
|
||||
};
|
||||
static char icon_mirror[11] = {0};
|
||||
|
||||
int pos, mask;
|
||||
|
||||
pos = icontab[icon].pos;
|
||||
mask = icontab[icon].mask;
|
||||
|
||||
if (enable)
|
||||
icon_mirror[pos] |= mask;
|
||||
else
|
||||
icon_mirror[pos] &= ~mask;
|
||||
|
||||
lcd_write_command_e(LCD_ICON(pos), icon_mirror[pos]);
|
||||
}
|
||||
|
||||
/* device specific init */
|
||||
void lcd_init_device(void)
|
||||
{
|
||||
unsigned char data_vector[64];
|
||||
|
||||
/* LCD init for cold start */
|
||||
PBCR2 &= 0xff00; /* Set PB0..PB3 to GPIO */
|
||||
or_b(0x0f, &PBDRL); /* ... high */
|
||||
or_b(0x0f, &PBIORL); /* ... and output */
|
||||
|
||||
new_lcd = is_new_player();
|
||||
|
||||
if (new_lcd)
|
||||
{
|
||||
lcd_contrast_set = NEW_LCD_CONTRAST_SET;
|
||||
lcd_ddram = NEW_LCD_DDRAM;
|
||||
lcd_cgram = NEW_LCD_CGRAM;
|
||||
lcd_iconram = NEW_LCD_ICONRAM;
|
||||
|
||||
lcd_write_command(NEW_LCD_FUNCTION_SET|1); /* CGRAM selected */
|
||||
lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08);
|
||||
lcd_write_command(NEW_LCD_SET_POWER_SAVE_OSC_CONTROL|2);
|
||||
/* oscillator on */
|
||||
lcd_write_command(NEW_LCD_SET_POWER_CONTROL_REG|7);
|
||||
/* opamp buffer + voltage booster on */
|
||||
|
||||
memset(data_vector, 0x20, 64);
|
||||
lcd_write_command(NEW_LCD_DDRAM); /* Set DDRAM address */
|
||||
lcd_write_data(data_vector, 64); /* all spaces */
|
||||
|
||||
memset(data_vector, 0, 64);
|
||||
lcd_write_command(NEW_LCD_CGRAM); /* Set CGRAM address */
|
||||
lcd_write_data(data_vector, 64); /* zero out */
|
||||
lcd_write_command(NEW_LCD_ICONRAM); /* Set ICONRAM address */
|
||||
lcd_write_data(data_vector, 16); /* zero out */
|
||||
|
||||
lcd_write_command(NEW_LCD_SET_DISPLAY_CONTROL|1); /* display on */
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_contrast_set = OLD_LCD_CONTRAST_SET;
|
||||
lcd_ddram = OLD_LCD_DDRAM;
|
||||
lcd_cgram = OLD_LCD_CGRAM;
|
||||
lcd_iconram = OLD_LCD_ICONRAM;
|
||||
|
||||
lcd_write_command(OLD_LCD_NOP);
|
||||
lcd_write_command(OLD_LCD_SYSTEM_SET|1); /* CGRAM selected */
|
||||
lcd_write_command(OLD_LCD_SET_POWER_SAVE_OSC_CONTROL|2);
|
||||
/* oscillator on */
|
||||
lcd_write_command(OLD_LCD_SET_POWER_CONTROL|7);
|
||||
/* voltage regulator, voltage follower and booster on */
|
||||
|
||||
memset(data_vector, 0x24, 13);
|
||||
lcd_write_command(OLD_LCD_DDRAM); /* Set DDRAM address */
|
||||
lcd_write_data(data_vector, 13); /* all spaces */
|
||||
lcd_write_command(OLD_LCD_DDRAM + 0x10);
|
||||
lcd_write_data(data_vector, 13);
|
||||
lcd_write_command(OLD_LCD_DDRAM + 0x20);
|
||||
lcd_write_data(data_vector, 13);
|
||||
|
||||
memset(data_vector, 0, 32);
|
||||
lcd_write_command(OLD_LCD_CGRAM); /* Set CGRAM address */
|
||||
lcd_write_data(data_vector, 32); /* zero out */
|
||||
lcd_write_command(OLD_LCD_ICONRAM); /* Set ICONRAM address */
|
||||
lcd_write_data(data_vector, 13); /* zero out */
|
||||
lcd_write_command(OLD_LCD_ICONRAM + 0x10);
|
||||
lcd_write_data(data_vector, 13);
|
||||
|
||||
sleep(HZ/10);
|
||||
lcd_write_command(OLD_LCD_SET_DISPLAY_CONTROL|1); /* display on */
|
||||
}
|
||||
lcd_set_contrast(lcd_default_contrast());
|
||||
}
|
||||
|
||||
/*** Update functions ***/
|
||||
|
||||
void lcd_update(void)
|
||||
{
|
||||
int y;
|
||||
|
||||
for (y = 0; y < lcd_pattern_count; y++)
|
||||
{
|
||||
if (lcd_patterns[y].count > 0)
|
||||
{
|
||||
lcd_write_command(lcd_cgram | (y << 3));
|
||||
lcd_write_data(lcd_patterns[y].pattern, 7);
|
||||
}
|
||||
}
|
||||
for (y = 0; y < LCD_HEIGHT; y++)
|
||||
{
|
||||
lcd_write_command(LCD_CURSOR(0, y));
|
||||
lcd_write_data(lcd_charbuffer[y], LCD_WIDTH);
|
||||
}
|
||||
if (lcd_cursor.visible)
|
||||
{
|
||||
lcd_write_command_e(LCD_CURSOR(lcd_cursor.x, lcd_cursor.y),
|
||||
lcd_cursor.hw_char);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include <stdbool.h>
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "usb.h"
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int power_input_status(void)
|
||||
{
|
||||
/* Player */
|
||||
return ((PADR & 1) == 0) ?
|
||||
POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
|
||||
}
|
||||
|
||||
void ide_power_enable(bool on)
|
||||
{
|
||||
bool touched = false;
|
||||
|
||||
if(on)
|
||||
{
|
||||
or_b(0x10, &PBDRL);
|
||||
touched = true;
|
||||
}
|
||||
#ifdef HAVE_ATA_POWER_OFF
|
||||
if(!on)
|
||||
{
|
||||
and_b(~0x10, &PBDRL);
|
||||
touched = true;
|
||||
}
|
||||
#endif /* HAVE_ATA_POWER_OFF */
|
||||
|
||||
/* late port preparation, else problems with read/modify/write
|
||||
of other bits on same port, while input and floating high */
|
||||
if (touched)
|
||||
{
|
||||
or_b(0x10, &PBIORL); /* PB4 is an output */
|
||||
PBCR2 &= ~0x0300; /* GPIO for PB4 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ide_powered(void)
|
||||
{
|
||||
/* This is not correct for very old players, since these are unable to
|
||||
* control hd power. However, driving the pin doesn't hurt, because it
|
||||
* is not connected anywhere */
|
||||
if ((PBCR2 & 0x0300) || !(PBIORL & 0x10)) /* not configured for output */
|
||||
return false; /* would be floating low, disk off */
|
||||
else
|
||||
return (PBDRL & 0x10) != 0;
|
||||
}
|
||||
|
||||
void power_off(void)
|
||||
{
|
||||
disable_irq();
|
||||
and_b(~0x08, &PADRH);
|
||||
or_b(0x08, &PAIORH);
|
||||
while(1);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "adc.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
4750
|
||||
};
|
||||
|
||||
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
4400
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
|
||||
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
|
||||
{
|
||||
/* original values were taken directly after charging, but it should show
|
||||
100% after turning off the device for some hours, too */
|
||||
{ 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 }
|
||||
/* orig. values: ...,5280,5600 */
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
|
||||
const unsigned short percent_to_volt_charge[11] =
|
||||
{
|
||||
/* values guessed, see
|
||||
http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone
|
||||
measures voltages over a charging cycle */
|
||||
4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */
|
||||
};
|
||||
|
||||
#define BATTERY_SCALE_FACTOR 6703
|
||||
/* full-scale ADC readout (2^10) in millivolt */
|
||||
|
||||
/* Returns battery voltage from ADC [millivolts] */
|
||||
int _battery_voltage(void)
|
||||
{
|
||||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include "cpu.h"
|
||||
#include "system.h"
|
||||
#include "usb.h"
|
||||
|
||||
int usb_detect(void)
|
||||
{
|
||||
return (PADR & 0x8000) ? USB_EXTRACTED : USB_INSERTED;
|
||||
}
|
||||
|
||||
void usb_enable(bool on)
|
||||
{
|
||||
if(on)
|
||||
and_b(~0x04, &PADRH);
|
||||
else
|
||||
or_b(0x04, &PADRH);
|
||||
}
|
||||
|
||||
void usb_init_device(void)
|
||||
{
|
||||
or_b(0x04, &PADRH);
|
||||
or_b(0x04, &PAIORH);
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _ADC_TARGET_H_
|
||||
#define _ADC_TARGET_H_
|
||||
|
||||
#define NUM_ADC_CHANNELS 8
|
||||
|
||||
/* normal JBR channel assignment */
|
||||
#define ADC_BATTERY 0 /* Battery voltage always reads 0x3FF due to
|
||||
silly scaling */
|
||||
#define ADC_CHARGE_REGULATOR 1 /* Regulator reference voltage, should read
|
||||
about 0x1c0 when charging, else 0x3FF */
|
||||
#define ADC_USB_POWER 2 /* USB, reads 0x3FF when USB is inserted */
|
||||
#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different
|
||||
voltages for different keys */
|
||||
#define ADC_BUTTON_ROW2 5 /* Used for scanning the keys, different
|
||||
voltages for different keys */
|
||||
#define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */
|
||||
#define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */
|
||||
|
||||
#define EXT_SCALE_FACTOR 14800
|
||||
|
||||
#endif /* _ADC_TARGET_H_ */
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef BACKLIGHT_TARGET_H
|
||||
#define BACKLIGHT_TARGET_H
|
||||
|
||||
#include "config.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#define backlight_hw_init() true
|
||||
|
||||
static inline void backlight_hw_on(void)
|
||||
{
|
||||
rtc_write(0x13, 0x10); /* 32 kHz square wave */
|
||||
rtc_write(0x0a, rtc_read(0x0a) | 0x40); /* Enable square wave */
|
||||
}
|
||||
|
||||
static inline void backlight_hw_off(void)
|
||||
{
|
||||
/* While on, backlight is flashing at 32 kHz. If the square wave output
|
||||
is disabled while the backlight is lit, it will become constantly lit,
|
||||
(brighter) and slowly fade. This resets the square wave counter and
|
||||
results in the unlit state */
|
||||
unsigned char rtc_0a = rtc_read(0x0a) & ~0x40;
|
||||
rtc_write(0x0a, rtc_0a); /* Disable square wave */
|
||||
rtc_write(0x13, 0xF0); /* 1 Hz square wave */
|
||||
rtc_write(0x0a, rtc_0a | 0x40); /* Enable square wave */
|
||||
|
||||
/* When the square wave output is disabled in the unlit state,
|
||||
the backlight stays off */
|
||||
rtc_write(0x0a, rtc_0a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
#include "backlight.h"
|
||||
#include "adc.h"
|
||||
|
||||
/*
|
||||
Recorder hardware button hookup
|
||||
===============================
|
||||
|
||||
F1, F2, F3, UP: connected to AN4 through a resistor network
|
||||
DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5
|
||||
|
||||
The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed
|
||||
|
||||
ON: PB8, low active
|
||||
OFF: PB4, low active
|
||||
*/
|
||||
|
||||
void button_init_device(void)
|
||||
{
|
||||
/* Set PB4 and PB8 as input pins */
|
||||
PBCR1 &= 0xfffc; /* PB8MD = 00 */
|
||||
PBCR2 &= 0xfcff; /* PB4MD = 00 */
|
||||
PBIOR &= ~0x0110; /* Inputs */
|
||||
}
|
||||
|
||||
int button_read_device(void)
|
||||
{
|
||||
int btn = BUTTON_NONE;
|
||||
int data;
|
||||
static int off_button_count = 0;
|
||||
|
||||
/* check F1..F3 and UP */
|
||||
data = adc_read(ADC_BUTTON_ROW1);
|
||||
if (data >= 250)
|
||||
{
|
||||
if (data >= 700)
|
||||
if (data >= 900)
|
||||
btn = BUTTON_F3;
|
||||
else
|
||||
btn = BUTTON_UP;
|
||||
else
|
||||
if (data >= 500)
|
||||
btn = BUTTON_F2;
|
||||
else
|
||||
btn = BUTTON_F1;
|
||||
}
|
||||
|
||||
/* Some units have mushy keypads, so pressing UP also activates
|
||||
the Left/Right buttons. Let's combat that by skipping the AN5
|
||||
checks when UP is pressed. */
|
||||
if(!(btn & BUTTON_UP))
|
||||
{
|
||||
/* check DOWN, PLAY, LEFT, RIGHT */
|
||||
data = adc_read(ADC_BUTTON_ROW2);
|
||||
if (data >= 250)
|
||||
{
|
||||
if (data >= 700)
|
||||
if (data >= 900)
|
||||
btn |= BUTTON_DOWN;
|
||||
else
|
||||
btn |= BUTTON_PLAY;
|
||||
else
|
||||
if (data >= 500)
|
||||
btn |= BUTTON_LEFT;
|
||||
else
|
||||
btn |= BUTTON_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/* check port B pins for ON and OFF */
|
||||
data = PBDR;
|
||||
if ((data & 0x0100) == 0)
|
||||
btn |= BUTTON_ON;
|
||||
|
||||
if ((data & 0x0010) == 0)
|
||||
{
|
||||
/* When the batteries are low, the low-battery shutdown logic causes
|
||||
* spurious OFF events due to voltage fluctuation on some units.
|
||||
* Only accept OFF when read several times in sequence. */
|
||||
if (++off_button_count > 3)
|
||||
btn |= BUTTON_OFF;
|
||||
}
|
||||
else
|
||||
off_button_count = 0;
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _BUTTON_TARGET_H_
|
||||
#define _BUTTON_TARGET_H_
|
||||
|
||||
#define HAS_SERIAL_REMOTE
|
||||
|
||||
/* Main unit's buttons */
|
||||
#define BUTTON_ON 0x00000001
|
||||
#define BUTTON_OFF 0x00000002
|
||||
|
||||
#define BUTTON_LEFT 0x00000004
|
||||
#define BUTTON_RIGHT 0x00000008
|
||||
#define BUTTON_UP 0x00000010
|
||||
#define BUTTON_DOWN 0x00000020
|
||||
|
||||
#define BUTTON_PLAY 0x00000040
|
||||
|
||||
#define BUTTON_F1 0x00000080
|
||||
#define BUTTON_F2 0x00000100
|
||||
#define BUTTON_F3 0x00000200
|
||||
|
||||
#define BUTTON_MAIN (BUTTON_ON|BUTTON_OFF|BUTTON_LEFT|BUTTON_RIGHT\
|
||||
|BUTTON_UP|BUTTON_DOWN|BUTTON_PLAY\
|
||||
|BUTTON_F1|BUTTON_F2|BUTTON_F3)
|
||||
|
||||
/* Remote control's buttons */
|
||||
#define BUTTON_RC_PLAY 0x00100000
|
||||
#define BUTTON_RC_STOP 0x00080000
|
||||
|
||||
#define BUTTON_RC_LEFT 0x00040000
|
||||
#define BUTTON_RC_RIGHT 0x00020000
|
||||
#define BUTTON_RC_VOL_UP 0x00010000
|
||||
#define BUTTON_RC_VOL_DOWN 0x00008000
|
||||
|
||||
#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
|
||||
|BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
|
||||
|BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
|
||||
|
||||
#endif /* _BUTTON_TARGET_H_ */
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include <stdbool.h>
|
||||
#include "adc.h"
|
||||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt-target.h"
|
||||
#include "usb.h"
|
||||
|
||||
static bool charger_on;
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
PBCR2 &= ~0x0c00; /* GPIO for PB5 */
|
||||
or_b(0x20, &PBIORL); /* Set charging control bit to output */
|
||||
charger_enable(false); /* Default to charger OFF */
|
||||
}
|
||||
|
||||
unsigned int power_input_status(void)
|
||||
{
|
||||
/* Recorder */
|
||||
return (adc_read(ADC_EXT_POWER) > 0x100) ?
|
||||
POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
|
||||
}
|
||||
|
||||
void charger_enable(bool on)
|
||||
{
|
||||
if(on)
|
||||
{
|
||||
and_b(~0x20, &PBDRL);
|
||||
}
|
||||
else
|
||||
{
|
||||
or_b(0x20, &PBDRL);
|
||||
}
|
||||
|
||||
charger_on = on;
|
||||
}
|
||||
|
||||
bool charger_enabled(void)
|
||||
{
|
||||
return charger_on;
|
||||
}
|
||||
|
||||
void ide_power_enable(bool on)
|
||||
{
|
||||
bool touched = false;
|
||||
|
||||
if(on)
|
||||
{
|
||||
or_b(0x20, &PADRL);
|
||||
touched = true;
|
||||
}
|
||||
#ifdef HAVE_ATA_POWER_OFF
|
||||
if(!on)
|
||||
{
|
||||
and_b(~0x20, &PADRL);
|
||||
touched = true;
|
||||
}
|
||||
#endif /* HAVE_ATA_POWER_OFF */
|
||||
|
||||
/* late port preparation, else problems with read/modify/write
|
||||
of other bits on same port, while input and floating high */
|
||||
if (touched)
|
||||
{
|
||||
or_b(0x20, &PAIORL); /* PA5 is an output */
|
||||
PACR2 &= 0xFBFF; /* GPIO for PA5 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ide_powered(void)
|
||||
{
|
||||
if ((PACR2 & 0x0400) || !(PAIORL & 0x20)) /* not configured for output */
|
||||
return true; /* would be floating high, disk on */
|
||||
else
|
||||
return (PADRL & 0x20) != 0;
|
||||
}
|
||||
|
||||
void power_off(void)
|
||||
{
|
||||
disable_irq();
|
||||
and_b(~0x10, &PBDRL);
|
||||
or_b(0x10, &PBIORL);
|
||||
while(1);
|
||||
}
|
||||
|
|
@ -1,501 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "storage.h"
|
||||
#include "adc.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
4750
|
||||
};
|
||||
|
||||
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
|
||||
{
|
||||
4400
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
|
||||
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
|
||||
{
|
||||
/* original values were taken directly after charging, but it should show
|
||||
100% after turning off the device for some hours, too */
|
||||
{ 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 }
|
||||
/* orig. values: ...,5280,5600 */
|
||||
};
|
||||
|
||||
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
|
||||
const unsigned short percent_to_volt_charge[11] =
|
||||
{
|
||||
/* values guessed, see
|
||||
http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone
|
||||
measures voltages over a charging cycle */
|
||||
4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */
|
||||
};
|
||||
|
||||
#define BATTERY_SCALE_FACTOR 6620
|
||||
/* full-scale ADC readout (2^10) in millivolt */
|
||||
|
||||
/* Returns battery voltage from ADC [millivolts] */
|
||||
int _battery_voltage(void)
|
||||
{
|
||||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
||||
void powermgmt_init_target(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** Charger control **/
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
#include "file.h"
|
||||
#define DEBUG_FILE_NAME "/powermgmt.csv"
|
||||
#define DEBUG_MESSAGE_LEN 133
|
||||
static char debug_message[DEBUG_MESSAGE_LEN];
|
||||
static int fd = -1; /* write debug information to this file */
|
||||
static int wrcount = 0;
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
|
||||
/*
|
||||
* For a complete description of the charging algorithm read
|
||||
* docs/CHARGING_ALGORITHM.
|
||||
*/
|
||||
int long_delta; /* long term delta battery voltage */
|
||||
int short_delta; /* short term delta battery voltage */
|
||||
static bool disk_activity_last_cycle = false; /* flag set to aid charger time
|
||||
* calculation */
|
||||
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
|
||||
debug menu */
|
||||
/* percentage at which charging
|
||||
starts */
|
||||
int powermgmt_last_cycle_startstop_min = 0; /* how many minutes ago was the
|
||||
charging started or
|
||||
stopped? */
|
||||
int powermgmt_last_cycle_level = 0; /* which level had the
|
||||
batteries at this time? */
|
||||
int trickle_sec = 0; /* how many seconds should the
|
||||
charger be enabled per
|
||||
minute for trickle
|
||||
charging? */
|
||||
int pid_p = 0; /* PID proportional term */
|
||||
int pid_i = 0; /* PID integral term */
|
||||
|
||||
static unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle
|
||||
* voltage level */
|
||||
static int charge_max_time_idle = 0; /* max. charging duration, calculated at
|
||||
* beginning of charging */
|
||||
static int charge_max_time_now = 0; /* max. charging duration including
|
||||
* hdd activity */
|
||||
static int minutes_disk_activity = 0; /* count minutes of hdd use during
|
||||
* charging */
|
||||
static int last_disk_activity = CHARGE_END_LONGD + 1; /* last hdd use x mins ago */
|
||||
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
static void debug_file_close(void)
|
||||
{
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_file_log(void)
|
||||
{
|
||||
if (usb_inserted()) {
|
||||
/* It is probably too late to close the file but we can try... */
|
||||
debug_file_close();
|
||||
}
|
||||
else if (fd < 0) {
|
||||
fd = open(DEBUG_FILE_NAME, O_WRONLY | O_APPEND | O_CREAT, 0666);
|
||||
|
||||
if (fd >= 0) {
|
||||
snprintf(debug_message, DEBUG_MESSAGE_LEN,
|
||||
"cycle_min, bat_millivolts, bat_percent, chgr_state"
|
||||
" ,charge_state, pid_p, pid_i, trickle_sec\n");
|
||||
write(fd, debug_message, strlen(debug_message));
|
||||
wrcount = 99; /* force a flush */
|
||||
}
|
||||
}
|
||||
else {
|
||||
snprintf(debug_message, DEBUG_MESSAGE_LEN,
|
||||
"%d, %d, %d, %d, %d, %d, %d, %d\n",
|
||||
powermgmt_last_cycle_startstop_min, battery_voltage(),
|
||||
battery_level(), charger_input_state, charge_state,
|
||||
pid_p, pid_i, trickle_sec);
|
||||
write(fd, debug_message, strlen(debug_message));
|
||||
wrcount++;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_file_sync(void)
|
||||
{
|
||||
/*
|
||||
* If we have a lot of pending writes or if the disk is spining,
|
||||
* fsync the debug log file.
|
||||
*/
|
||||
if (wrcount > 10 || (wrcount > 0 && storage_disk_is_active())) {
|
||||
if (fd >= 0)
|
||||
fsync(fd);
|
||||
|
||||
wrcount = 0;
|
||||
}
|
||||
}
|
||||
#else /* !CHARGING_DEBUG_FILE */
|
||||
#define debug_file_close()
|
||||
#define debug_file_log()
|
||||
#define debug_file_sync()
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
|
||||
/*
|
||||
* Do tasks that should be done every step.
|
||||
*/
|
||||
static void do_frequent_tasks(void)
|
||||
{
|
||||
if (storage_disk_is_active()) {
|
||||
/* flag hdd use for charging calculation */
|
||||
disk_activity_last_cycle = true;
|
||||
}
|
||||
|
||||
debug_file_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* The charger was just plugged in. If the battery level is
|
||||
* nearly charged, just trickle. If the battery is low, start
|
||||
* a full charge cycle. If the battery level is in between,
|
||||
* top-off and then trickle.
|
||||
*/
|
||||
static void charger_plugged(void)
|
||||
{
|
||||
int battery_percent = battery_level();
|
||||
|
||||
pid_p = 0;
|
||||
pid_i = 0;
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN, "Charger plugged in");
|
||||
|
||||
if (battery_percent > START_TOPOFF_CHG) {
|
||||
|
||||
if (battery_percent >= START_TRICKLE_CHG) {
|
||||
charge_state = TRICKLE;
|
||||
target_voltage = TRICKLE_VOLTAGE;
|
||||
}
|
||||
else {
|
||||
charge_state = TOPOFF;
|
||||
target_voltage = TOPOFF_VOLTAGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Start the charger full strength
|
||||
*/
|
||||
int i = CHARGE_MAX_MIN_1500 * get_battery_capacity() / 1500;
|
||||
charge_max_time_idle = i * (100 + 35 - battery_percent) / 100;
|
||||
|
||||
if (charge_max_time_idle > i)
|
||||
charge_max_time_idle = i;
|
||||
|
||||
charge_max_time_now = charge_max_time_idle;
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"ChgAt %d%% max %dm", battery_percent,
|
||||
charge_max_time_now);
|
||||
|
||||
/*
|
||||
* Enable the charger after the max time calc is done,
|
||||
* because battery_level depends on if the charger is
|
||||
* on.
|
||||
*/
|
||||
DEBUGF("power: charger inserted and battery"
|
||||
" not full, charging\n");
|
||||
trickle_sec = 60;
|
||||
long_delta = short_delta = 999999;
|
||||
charge_state = CHARGING;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The charger was just unplugged.
|
||||
*/
|
||||
static void charger_unplugged(void)
|
||||
{
|
||||
DEBUGF("power: charger disconnected, disabling\n");
|
||||
|
||||
charger_enable(false);
|
||||
powermgmt_last_cycle_level = battery_level();
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
trickle_sec = 0;
|
||||
pid_p = 0;
|
||||
pid_i = 0;
|
||||
charge_state = DISCHARGING;
|
||||
snprintf(power_message, POWER_MESSAGE_LEN, "Charger: discharge");
|
||||
}
|
||||
|
||||
static void charging_step(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* alter charge time max length with extra disk use */
|
||||
if (disk_activity_last_cycle) {
|
||||
minutes_disk_activity++;
|
||||
charge_max_time_now = charge_max_time_idle +
|
||||
minutes_disk_activity*2 / 5;
|
||||
disk_activity_last_cycle = false;
|
||||
last_disk_activity = 0;
|
||||
}
|
||||
else {
|
||||
last_disk_activity++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the delta voltage over the last X minutes so we can do
|
||||
* our end-of-charge logic based on the battery level change
|
||||
* (no longer use minimum time as logic for charge end has 50
|
||||
* minutes minimum charge built in).
|
||||
*/
|
||||
if (powermgmt_last_cycle_startstop_min > CHARGE_END_SHORTD) {
|
||||
short_delta = power_history[0] -
|
||||
power_history[CHARGE_END_SHORTD - 1];
|
||||
}
|
||||
|
||||
if (powermgmt_last_cycle_startstop_min > CHARGE_END_LONGD) {
|
||||
/*
|
||||
* Scan the history: the points where measurement is taken need to
|
||||
* be fairly static. Check prior to short delta 'area'. Also only
|
||||
* check first and last 10 cycles (delta in middle OK).
|
||||
*/
|
||||
long_delta = power_history[0] -
|
||||
power_history[CHARGE_END_LONGD - 1];
|
||||
|
||||
for (i = CHARGE_END_SHORTD; i < CHARGE_END_SHORTD + 10; i++)
|
||||
{
|
||||
if ((power_history[i] - power_history[i+1]) > 50 ||
|
||||
(power_history[i] - power_history[i+1]) < -50) {
|
||||
long_delta = 777777;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = CHARGE_END_LONGD - 11; i < CHARGE_END_LONGD - 1 ; i++)
|
||||
{
|
||||
if ((power_history[i] - power_history[i+1]) > 50 ||
|
||||
(power_history[i] - power_history[i+1]) < -50) {
|
||||
long_delta = 888888;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"Chg %dm, max %dm", powermgmt_last_cycle_startstop_min,
|
||||
charge_max_time_now);
|
||||
|
||||
/*
|
||||
* End of charge criteria (any qualify):
|
||||
* 1) Charged a long time
|
||||
* 2) DeltaV went negative for a short time ( & long delta static)
|
||||
* 3) DeltaV was negative over a longer period (no disk use only)
|
||||
*
|
||||
* Note: short_delta and long_delta are millivolts
|
||||
*/
|
||||
if (powermgmt_last_cycle_startstop_min >= charge_max_time_now ||
|
||||
(short_delta <= -50 && long_delta < 50) ||
|
||||
(long_delta < -20 && last_disk_activity > CHARGE_END_LONGD)) {
|
||||
|
||||
int battery_percent = battery_level();
|
||||
|
||||
if (powermgmt_last_cycle_startstop_min > charge_max_time_now) {
|
||||
DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, "
|
||||
"enough!\n");
|
||||
/*
|
||||
* Have charged too long and deltaV detection did not
|
||||
* work!
|
||||
*/
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"Chg tmout %d min", charge_max_time_now);
|
||||
/*
|
||||
* Switch to trickle charging. We skip the top-off
|
||||
* since we've effectively done the top-off operation
|
||||
* already since we charged for the maximum full
|
||||
* charge time.
|
||||
*/
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TRICKLE;
|
||||
|
||||
/*
|
||||
* Set trickle charge target to a relative voltage instead
|
||||
* of an arbitrary value - the fully charged voltage may
|
||||
* vary according to ambient temp, battery condition etc.
|
||||
* Trickle target is -0.15v from full voltage acheived.
|
||||
* Topup target is -0.05v from full voltage.
|
||||
*/
|
||||
target_voltage = power_history[0] - 150;
|
||||
|
||||
}
|
||||
else {
|
||||
if(short_delta <= -5) {
|
||||
DEBUGF("power: short-term negative"
|
||||
" delta, enough!\n");
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"end negd %d %dmin", short_delta,
|
||||
powermgmt_last_cycle_startstop_min);
|
||||
target_voltage = power_history[CHARGE_END_SHORTD - 1] - 50;
|
||||
}
|
||||
else {
|
||||
DEBUGF("power: long-term small "
|
||||
"positive delta, enough!\n");
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"end lowd %d %dmin", long_delta,
|
||||
powermgmt_last_cycle_startstop_min);
|
||||
target_voltage = power_history[CHARGE_END_LONGD - 1] - 50;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch to top-off charging.
|
||||
*/
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TOPOFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void topoff_trickle_step(void)
|
||||
{
|
||||
unsigned int millivolts;
|
||||
|
||||
/*
|
||||
*Time to switch from topoff to trickle?
|
||||
*/
|
||||
if (charge_state == TOPOFF &&
|
||||
powermgmt_last_cycle_startstop_min > TOPOFF_MAX_MIN) {
|
||||
|
||||
powermgmt_last_cycle_level = battery_level();
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TRICKLE;
|
||||
target_voltage = target_voltage - 100;
|
||||
}
|
||||
/*
|
||||
* Adjust trickle charge time (proportional and integral terms).
|
||||
* Note: I considered setting the level higher if the USB is
|
||||
* plugged in, but it doesn't appear to be necessary and will
|
||||
* generate more heat [gvb].
|
||||
*/
|
||||
millivolts = battery_voltage();
|
||||
|
||||
pid_p = ((signed)target_voltage - (signed)millivolts) / 5;
|
||||
if (pid_p <= PID_DEADZONE && pid_p >= -PID_DEADZONE)
|
||||
pid_p = 0;
|
||||
|
||||
if ((unsigned)millivolts < target_voltage) {
|
||||
if (pid_i < 60)
|
||||
pid_i++; /* limit so it doesn't "wind up" */
|
||||
}
|
||||
else {
|
||||
if (pid_i > 0)
|
||||
pid_i--; /* limit so it doesn't "wind up" */
|
||||
}
|
||||
|
||||
trickle_sec = pid_p + pid_i;
|
||||
|
||||
if (trickle_sec > 60)
|
||||
trickle_sec = 60;
|
||||
|
||||
if (trickle_sec < 0)
|
||||
trickle_sec = 0;
|
||||
}
|
||||
|
||||
void charging_algorithm_step(void)
|
||||
{
|
||||
static int pwm_counter = 0; /* PWM total cycle in steps */
|
||||
static int pwm_duty = 0; /* PWM duty cycle in steps */
|
||||
|
||||
switch (charger_input_state)
|
||||
{
|
||||
case CHARGER_PLUGGED:
|
||||
charger_plugged();
|
||||
break;
|
||||
|
||||
case CHARGER_UNPLUGGED:
|
||||
charger_unplugged();
|
||||
break;
|
||||
|
||||
case CHARGER:
|
||||
case NO_CHARGER:
|
||||
do_frequent_tasks();
|
||||
|
||||
if (pwm_counter > 0) {
|
||||
if (pwm_duty > 0 && --pwm_duty <= 0)
|
||||
charger_enable(false); /* Duty cycle expired */
|
||||
|
||||
if (--pwm_counter > 0)
|
||||
return;
|
||||
|
||||
/* PWM cycle is complete */
|
||||
powermgmt_last_cycle_startstop_min++;
|
||||
debug_file_log();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (charge_state)
|
||||
{
|
||||
case CHARGING:
|
||||
charging_step();
|
||||
break;
|
||||
|
||||
case TOPOFF:
|
||||
case TRICKLE:
|
||||
topoff_trickle_step();
|
||||
break;
|
||||
|
||||
case DISCHARGING:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If 100%, ensure pwm_on never expires and briefly disables the
|
||||
* charger. */
|
||||
pwm_duty = (trickle_sec < 60) ? trickle_sec*2 : 0;
|
||||
pwm_counter = 60*2;
|
||||
charger_enable(trickle_sec > 0);
|
||||
}
|
||||
|
||||
void charging_algorithm_close(void)
|
||||
{
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
debug_file_close();
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
}
|
||||
|
||||
/* Returns true if the unit is charging the batteries. */
|
||||
bool charging_state(void)
|
||||
{
|
||||
return charge_state == CHARGING;
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef POWERMGMT_TARGET_H
|
||||
#define POWERMGMT_TARGET_H
|
||||
|
||||
/*
|
||||
* Define CHARGING_DEBUG_FILE to create a csv (spreadsheet) with battery
|
||||
* information in it (one sample per minute/connect/disconnect).
|
||||
*
|
||||
* This is only for very low level debug.
|
||||
*/
|
||||
#undef CHARGING_DEBUG_FILE
|
||||
|
||||
|
||||
/* stop when N minutes have passed with avg delta being < -0.05 V */
|
||||
#define CHARGE_END_SHORTD 6
|
||||
/* stop when N minutes have passed with avg delta being < -0.02 V */
|
||||
#define CHARGE_END_LONGD 50
|
||||
|
||||
/* Battery % to start at top-off */
|
||||
#define START_TOPOFF_CHG 85
|
||||
/* Battery % to start at trickle */
|
||||
#define START_TRICKLE_CHG 95
|
||||
/* power thread status message */
|
||||
#define POWER_MESSAGE_LEN 32
|
||||
/* minutes: maximum charging time for 1500 mAh batteries
|
||||
* actual max time depends also on BATTERY_CAPACITY! */
|
||||
#define CHARGE_MAX_MIN_1500 450
|
||||
/* minutes: minimum charging time */
|
||||
#define CHARGE_MIN_MIN 10
|
||||
/* After charging, go to top off charge. How long should top off charge be? */
|
||||
#define TOPOFF_MAX_MIN 90
|
||||
/* which voltage is best? (millivolts) */
|
||||
#define TOPOFF_VOLTAGE 5650
|
||||
/* After top off charge, go to trickle harge. How long should trickle
|
||||
* charge be? */
|
||||
#define TRICKLE_MAX_MIN 720 /* 12 hrs */
|
||||
/* which voltage is best? (millivolts) */
|
||||
#define TRICKLE_VOLTAGE 5450
|
||||
/* initial trickle_sec for topoff */
|
||||
#define START_TOPOFF_SEC 25
|
||||
/* initial trickle_sec for trickle */
|
||||
#define START_TRICKLE_SEC 15
|
||||
|
||||
#define PID_DEADZONE 4 /* PID proportional deadzone */
|
||||
|
||||
extern char power_message[POWER_MESSAGE_LEN];
|
||||
|
||||
extern int long_delta; /* long term delta battery voltage */
|
||||
extern int short_delta; /* short term delta battery voltage */
|
||||
|
||||
extern int powermgmt_last_cycle_startstop_min; /* how many minutes ago was
|
||||
the charging started or
|
||||
stopped? */
|
||||
extern int powermgmt_last_cycle_level; /* which level had the batteries
|
||||
at this time? */
|
||||
|
||||
extern int pid_p; /* PID proportional term */
|
||||
extern int pid_i; /* PID integral term */
|
||||
extern int trickle_sec; /* how many seconds should the
|
||||
charger be enabled per
|
||||
minute for trickle
|
||||
charging? */
|
||||
void charger_enable(bool on);
|
||||
bool charger_enabled(void);
|
||||
|
||||
/* Battery filter lengths in samples */
|
||||
#define BATT_AVE_SAMPLES 32
|
||||
|
||||
#endif /* POWERMGMT_TARGET_H */
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include "adc.h"
|
||||
#include "cpu.h"
|
||||
#include "hwcompat.h"
|
||||
#include "system.h"
|
||||
#include "usb.h"
|
||||
|
||||
int usb_detect(void)
|
||||
{
|
||||
return (adc_read(ADC_USB_POWER) > 500) ? USB_INSERTED : USB_EXTRACTED;
|
||||
}
|
||||
|
||||
void usb_enable(bool on)
|
||||
{
|
||||
if(HW_MASK & USB_ACTIVE_HIGH)
|
||||
on = !on;
|
||||
|
||||
if(on)
|
||||
and_b(~0x04, &PADRH); /* enable USB */
|
||||
else
|
||||
or_b(0x04, &PADRH);
|
||||
}
|
||||
|
||||
void usb_init_device(void)
|
||||
{
|
||||
usb_enable(false);
|
||||
or_b(0x04, &PAIORH);
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
|
||||
void IMIA4(void) __attribute__((interrupt_handler));
|
||||
void IMIA4(void)
|
||||
{
|
||||
if (pfn_timer != NULL)
|
||||
pfn_timer();
|
||||
and_b(~0x01, &TSR4); /* clear the interrupt */
|
||||
}
|
||||
|
||||
bool timer_set(long cycles, bool start)
|
||||
{
|
||||
int phi = 0; /* bits for the prescaler */
|
||||
int prescale = 1;
|
||||
|
||||
while (cycles > 0x10000)
|
||||
{ /* work out the smallest prescaler that makes it fit */
|
||||
phi++;
|
||||
prescale <<= 1;
|
||||
cycles >>= 1;
|
||||
}
|
||||
|
||||
if (prescale > 8)
|
||||
return false;
|
||||
|
||||
if (start)
|
||||
{
|
||||
if (pfn_unregister != NULL)
|
||||
{
|
||||
pfn_unregister();
|
||||
pfn_unregister = NULL;
|
||||
}
|
||||
|
||||
and_b(~0x10, &TSTR); /* Stop the timer 4 */
|
||||
and_b(~0x10, &TSNC); /* No synchronization */
|
||||
and_b(~0x10, &TMDR); /* Operate normally */
|
||||
|
||||
TIER4 = 0xF9; /* Enable GRA match interrupt */
|
||||
}
|
||||
|
||||
TCR4 = 0x20 | phi; /* clear at GRA match, set prescaler */
|
||||
GRA4 = (unsigned short)(cycles - 1);
|
||||
if (start || (TCNT4 >= GRA4))
|
||||
TCNT4 = 0;
|
||||
and_b(~0x01, &TSR4); /* clear an eventual interrupt */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timer_start(void)
|
||||
{
|
||||
IPRD = (IPRD & 0xFF0F) | 1 << 4; /* interrupt priority */
|
||||
or_b(0x10, &TSTR); /* start timer 4 */
|
||||
return true;
|
||||
}
|
||||
|
||||
void timer_stop(void)
|
||||
{
|
||||
and_b(~0x10, &TSTR); /* stop the timer 4 */
|
||||
IPRD = (IPRD & 0xFF0F); /* disable interrupt */
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Alan Korr & Nick Robinson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "button.h"
|
||||
#include "cpu.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "serial.h"
|
||||
|
||||
/* FIX: this doesn't work on iRiver or iPod yet */
|
||||
/* iFP7xx has no remote */
|
||||
|
||||
/* Received byte identifiers */
|
||||
#define PLAY 0xC1
|
||||
#define STOP 0xC2
|
||||
#define PREV 0xC4
|
||||
#define NEXT 0xC8
|
||||
#define VOLUP 0xD0
|
||||
#define VOLDN 0xE0
|
||||
|
||||
void serial_setup (void)
|
||||
{
|
||||
/* Set PB10 function to serial Rx */
|
||||
PBCR1 = (PBCR1 & 0xffcf) | 0x0020;
|
||||
|
||||
SMR1 = 0x00;
|
||||
SCR1 = 0;
|
||||
BRR1 = (FREQ/(32*9600))-1;
|
||||
and_b(0, &SSR1); /* The status bits must be read before they are cleared,
|
||||
so we do an AND operation */
|
||||
|
||||
/* Let the hardware settle. The serial port needs to wait "at least
|
||||
the interval required to transmit or receive one bit" before it
|
||||
can be used. */
|
||||
sleep(1);
|
||||
|
||||
SCR1 = 0x10; /* Enable the receiver, no interrupt */
|
||||
}
|
||||
|
||||
int tx_rdy(void)
|
||||
{
|
||||
/* a dummy */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rx_rdy(void)
|
||||
{
|
||||
if(SSR1 & SCI_RDRF)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tx_writec(unsigned char c)
|
||||
{
|
||||
/* a dummy */
|
||||
(void)c;
|
||||
}
|
||||
|
||||
static unsigned char rx_readc(void)
|
||||
{
|
||||
char tmp;
|
||||
/* Read byte and clear the Rx Full bit */
|
||||
tmp = RDR1;
|
||||
and_b(~SCI_RDRF, &SSR1);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* This function returns the received remote control code only if it is
|
||||
received without errors before or after the reception.
|
||||
It therefore returns the received code on the second call after the
|
||||
code has been received. */
|
||||
int remote_control_rx(void)
|
||||
{
|
||||
static int last_valid_button = BUTTON_NONE;
|
||||
static int last_was_error = false;
|
||||
int btn;
|
||||
int ret = BUTTON_NONE;
|
||||
|
||||
/* Errors? Just clear'em. The receiver stops if we don't */
|
||||
if(SSR1 & (SCI_ORER | SCI_FER | SCI_PER)) {
|
||||
and_b(~(SCI_ORER | SCI_FER | SCI_PER), &SSR1);
|
||||
last_valid_button = BUTTON_NONE;
|
||||
last_was_error = true;
|
||||
return BUTTON_NONE;
|
||||
}
|
||||
|
||||
if(rx_rdy()) {
|
||||
btn = rx_readc();
|
||||
|
||||
if(last_was_error)
|
||||
{
|
||||
last_valid_button = BUTTON_NONE;
|
||||
ret = BUTTON_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case STOP:
|
||||
last_valid_button = BUTTON_RC_STOP;
|
||||
break;
|
||||
|
||||
case PLAY:
|
||||
last_valid_button = BUTTON_RC_PLAY;
|
||||
break;
|
||||
|
||||
case VOLUP:
|
||||
last_valid_button = BUTTON_RC_VOL_UP;
|
||||
break;
|
||||
|
||||
case VOLDN:
|
||||
last_valid_button = BUTTON_RC_VOL_DOWN;
|
||||
break;
|
||||
|
||||
case PREV:
|
||||
last_valid_button = BUTTON_RC_LEFT;
|
||||
break;
|
||||
|
||||
case NEXT:
|
||||
last_valid_button = BUTTON_RC_RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
last_valid_button = BUTTON_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This means that a valid remote control character was received
|
||||
the last time we were called, with no receiver errors either before
|
||||
or after. Then we can assume that there really is a remote control
|
||||
attached, and return the button code. */
|
||||
ret = last_valid_button;
|
||||
last_valid_button = BUTTON_NONE;
|
||||
}
|
||||
|
||||
last_was_error = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 by Jens Arnold
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.section .icode,"ax",@progbits
|
||||
.align 2
|
||||
.global _bitswap
|
||||
.type _bitswap,@function
|
||||
|
||||
/* Flips the bits of all bytes in a memory area (required for mp3 data on
|
||||
* the Archos). This version is optimized for speed and size.
|
||||
*
|
||||
* arguments:
|
||||
* r4 - start address
|
||||
* r5 - length
|
||||
*
|
||||
* return value: void
|
||||
*
|
||||
* register usage:
|
||||
* r0 - temporary
|
||||
* r1 - bit mask for rounding to long bound / low byte (after swap)
|
||||
* r2 - high byte (after swap) / combined result
|
||||
* r4 - data address - 4
|
||||
* r5 - end address - 4
|
||||
* r7 - flip table (addressing with signed offset)
|
||||
*
|
||||
* The instruction order below is devised in a way to utilize the pipelining
|
||||
* of the SH1 to the max.
|
||||
*/
|
||||
|
||||
_bitswap:
|
||||
mova _fliptable,r0
|
||||
mov r0,r7
|
||||
add #-4,r4 /* address is shifted by 4 */
|
||||
add r4,r5 /* r5 = end_address - 4 */
|
||||
cmp/hi r4,r5 /* at least something to do? */
|
||||
bf .exit /* no, get out of here! */
|
||||
|
||||
add #-3,r5 /* end offset for flipping 4 bytes per pass */
|
||||
mov r4,r0
|
||||
tst #1,r0 /* even address? */
|
||||
bt .start2_w /* yes, jump into main loop */
|
||||
|
||||
/* no, flip first byte */
|
||||
mov.b @(4,r4),r0 /* load byte, sign extension! */
|
||||
add #1,r4 /* early increment */
|
||||
mov.b @(r0,r7),r0 /* fliptable offset is signed */
|
||||
bra .start2_w /* jump into main loop */
|
||||
mov.b r0,@(3,r4) /* store byte */
|
||||
|
||||
/* main loop: flips 2 words per pass */
|
||||
.align 2
|
||||
.loop2_w:
|
||||
mov.w @(6,r4),r0 /* load second word */
|
||||
add #4,r4 /* early increment */
|
||||
swap.b r0,r2 /* get high byte (2nd word) */
|
||||
exts.b r0,r0 /* prepare low byte (2nd word) */
|
||||
mov.b @(r0,r7),r1 /* swap low byte (2nd word) */
|
||||
exts.b r2,r0 /* prepare high byte (2nd word) */
|
||||
mov.b @(r0,r7),r2 /* swap high byte (2nd word) */
|
||||
extu.b r1,r0 /* zero extend low byte (2nd word) */
|
||||
mov.w @r4,r1 /* load first word */
|
||||
shll8 r2 /* shift high byte (2nd word), low byte zeroed */
|
||||
or r2,r0 /* put low byte (2nd word) in result */
|
||||
swap.b r1,r2 /* get high byte (1st word) */
|
||||
mov.w r0,@(2,r4) /* store result (2nd word) */
|
||||
exts.b r1,r0 /* prepare low byte (1st word) */
|
||||
mov.b @(r0,r7),r1 /* swap low byte (1st word) */
|
||||
exts.b r2,r0 /* prepare high byte (1st word) */
|
||||
mov.b @(r0,r7),r2 /* swap high byte (1st word) */
|
||||
extu.b r1,r0 /* zero extend low byte (1st word) */
|
||||
shll8 r2 /* shift high byte (1st word), low byte zeroed */
|
||||
or r2,r0 /* put low byte (1st word) in result */
|
||||
mov.w r0,@r4 /* store result (1st word) */
|
||||
.start2_w:
|
||||
cmp/hi r4,r5 /* runs r4 up to last long bound */
|
||||
bt .loop2_w
|
||||
|
||||
bra .start_b2 /* jump into trailing byte loop */
|
||||
add #3,r5 /* reset end offset */
|
||||
|
||||
/* trailing byte loop: flips 0..3 bytes */
|
||||
.loop_b2:
|
||||
mov.b @(4,r4),r0 /* loand byte, sign extension! */
|
||||
add #1,r4 /* early increment */
|
||||
mov.b @(r0,r7),r0 /* fliptable offset is signed */
|
||||
mov.b r0,@(3,r4) /* store byte */
|
||||
.start_b2:
|
||||
cmp/hi r4,r5 /* runs r4 up to end address */
|
||||
bt .loop_b2
|
||||
|
||||
.exit:
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
.global _fliptable
|
||||
|
||||
.byte 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1
|
||||
.byte 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1
|
||||
.byte 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9
|
||||
.byte 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9
|
||||
.byte 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5
|
||||
.byte 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5
|
||||
.byte 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed
|
||||
.byte 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd
|
||||
.byte 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3
|
||||
.byte 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3
|
||||
.byte 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb
|
||||
.byte 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb
|
||||
.byte 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7
|
||||
.byte 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7
|
||||
.byte 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef
|
||||
.byte 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||
_fliptable:
|
||||
.byte 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0
|
||||
.byte 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
|
||||
.byte 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8
|
||||
.byte 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8
|
||||
.byte 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4
|
||||
.byte 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4
|
||||
.byte 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec
|
||||
.byte 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc
|
||||
.byte 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2
|
||||
.byte 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2
|
||||
.byte 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea
|
||||
.byte 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa
|
||||
.byte 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6
|
||||
.byte 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6
|
||||
.byte 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee
|
||||
.byte 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe
|
||||
|
||||
|
||||
.end:
|
||||
.size _bitswap,.end-_bitswap
|
||||
|
|
@ -1,219 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
.section .init.text,"ax",@progbits
|
||||
|
||||
.global start
|
||||
start:
|
||||
|
||||
mov.l .vbr_k,r1
|
||||
#ifdef DEBUG
|
||||
/* If we have built our code to be loaded via the standalone GDB
|
||||
* stub, we will have out VBR at some other location than 0x9000000.
|
||||
* We must copy the trap vectors for the GDB stub to our vector table. */
|
||||
mov.l .orig_vbr_k,r2
|
||||
|
||||
/* Move the invalid instruction vector (4) */
|
||||
mov #4,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the invalid slot vector (6) */
|
||||
mov #6,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the bus error vector (9) */
|
||||
mov #9,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the DMA bus error vector (10) */
|
||||
mov #10,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the NMI vector as well (11) */
|
||||
mov #11,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the UserBreak vector as well (12) */
|
||||
mov #12,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the breakpoint trap vector (32) */
|
||||
mov #32,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the IO trap vector (33) */
|
||||
mov #33,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the serial Rx interrupt vector (105) */
|
||||
mov #105,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
|
||||
/* Move the single step trap vector (127) */
|
||||
mov #127,r0
|
||||
shll2 r0
|
||||
mov.l @(r0,r2),r3
|
||||
mov.l r3,@(r0,r1)
|
||||
#endif /* DEBUG */
|
||||
ldc r1,vbr
|
||||
|
||||
mov #0,r0
|
||||
ldc r0,gbr
|
||||
|
||||
/* .iram copy is done first since it is reclaimed for other
|
||||
* uninitialized sections */
|
||||
|
||||
/* copy the .iram section */
|
||||
mov.l .iramcopy_k,r0
|
||||
mov.l .iram_k,r1
|
||||
mov.l .iramend_k,r2
|
||||
/* Note: We cannot put a PC relative load into the delay slot of a 'bra'
|
||||
instruction (the offset would be wrong), but there is nothing else to
|
||||
do before the loop, so the delay slot would be 'nop'. The cmp / bf
|
||||
sequence is the same length, but more efficient. */
|
||||
cmp/hi r1,r2
|
||||
bf .noiramcopy
|
||||
.iramloop:
|
||||
mov.l @r0+,r3
|
||||
mov.l r3,@r1
|
||||
add #4,r1
|
||||
cmp/hi r1,r2
|
||||
bt .iramloop
|
||||
.noiramcopy:
|
||||
|
||||
/* zero out .ibss */
|
||||
mov.l .iedata_k,r0
|
||||
mov.l .iend_k,r1
|
||||
bra .iedatastart
|
||||
mov #0,r2
|
||||
.iedataloop: /* backwards is faster and shorter */
|
||||
mov.l r2,@-r1
|
||||
.iedatastart:
|
||||
cmp/hi r0,r1
|
||||
bt .iedataloop
|
||||
|
||||
/* zero out bss */
|
||||
mov.l .edata_k,r0
|
||||
mov.l .end_k,r1
|
||||
bra .edatastart
|
||||
mov #0,r2
|
||||
.edataloop: /* backwards is faster and shorter */
|
||||
mov.l r2,@-r1
|
||||
.edatastart:
|
||||
cmp/hi r0,r1
|
||||
bt .edataloop
|
||||
|
||||
/* copy the .data section, for rombased execution */
|
||||
mov.l .datacopy_k,r0
|
||||
mov.l .data_k,r1
|
||||
cmp/eq r0,r1
|
||||
bt .nodatacopy /* Don't copy if src and dest are equal */
|
||||
mov.l .dataend_k,r2
|
||||
cmp/hi r1,r2
|
||||
bf .nodatacopy
|
||||
.dataloop:
|
||||
mov.l @r0+,r3
|
||||
mov.l r3,@r1
|
||||
add #4,r1
|
||||
cmp/hi r1,r2
|
||||
bt .dataloop
|
||||
.nodatacopy:
|
||||
|
||||
/* Munge the main thread stack */
|
||||
mov.l .stackbegin_k,r0
|
||||
mov.l .stackend_k,r1
|
||||
mov r1,r15
|
||||
mov.l .deadbeef_k,r2
|
||||
.mungeloop: /* backwards is faster and shorter */
|
||||
mov.l r2,@-r1
|
||||
cmp/hi r0,r1
|
||||
bt .mungeloop
|
||||
|
||||
/* call the mainline */
|
||||
mov.l .main_k,r0
|
||||
jsr @r0
|
||||
nop
|
||||
.hoo:
|
||||
bra .hoo
|
||||
nop
|
||||
|
||||
.align 2
|
||||
.vbr_k:
|
||||
.long vectors
|
||||
#ifdef DEBUG
|
||||
.orig_vbr_k:
|
||||
.long 0x09000000
|
||||
#endif
|
||||
.iedata_k:
|
||||
.long _iedata
|
||||
.iend_k:
|
||||
.long _iend
|
||||
.iramcopy_k:
|
||||
.long _iramcopy
|
||||
.iram_k:
|
||||
.long _iramstart
|
||||
.iramend_k:
|
||||
.long _iramend
|
||||
.edata_k:
|
||||
.long _edata
|
||||
.end_k:
|
||||
.long _end
|
||||
.datacopy_k:
|
||||
.long _datacopy
|
||||
.data_k:
|
||||
.long _datastart
|
||||
.dataend_k:
|
||||
.long _dataend
|
||||
.stackbegin_k:
|
||||
.long _stackbegin
|
||||
.stackend_k:
|
||||
.long _stackend
|
||||
.deadbeef_k:
|
||||
.long 0xdeadbeef
|
||||
.main_k:
|
||||
.long _main
|
||||
|
||||
.section .resetvectors
|
||||
vectors:
|
||||
.long start
|
||||
.long _stackend
|
||||
.long start
|
||||
.long _stackend
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 Heikki Hannikainen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "font.h"
|
||||
#include "lcd.h"
|
||||
#include "button.h"
|
||||
#include "powermgmt.h"
|
||||
#include "adc.h"
|
||||
#include "hwcompat.h" /* ROM_VERSION */
|
||||
#include "crc32.h"
|
||||
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
# define DEBUG_CANCEL BUTTON_OFF
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
# define DEBUG_CANCEL BUTTON_MENU
|
||||
#endif
|
||||
|
||||
/* Tool function to read the flash manufacturer and type, if available.
|
||||
Only chips which could be reprogrammed in system will return values.
|
||||
(The mode switch addresses vary between flash manufacturers, hence addr1/2) */
|
||||
/* In IRAM to avoid problems when running directly from Flash */
|
||||
static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
|
||||
unsigned addr1, unsigned addr2)
|
||||
ICODE_ATTR __attribute__((noinline));
|
||||
static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
|
||||
unsigned addr1, unsigned addr2)
|
||||
{
|
||||
unsigned not_manu, not_id; /* read values before switching to ID mode */
|
||||
unsigned manu, id; /* read values when in ID mode */
|
||||
|
||||
volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
|
||||
int old_level; /* saved interrupt level */
|
||||
|
||||
not_manu = flash[0]; /* read the normal content */
|
||||
not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
|
||||
|
||||
/* disable interrupts, prevent any stray flash access */
|
||||
old_level = disable_irq_save();
|
||||
|
||||
flash[addr1] = 0xAA; /* enter command mode */
|
||||
flash[addr2] = 0x55;
|
||||
flash[addr1] = 0x90; /* ID command */
|
||||
/* Atmel wants 20ms pause here */
|
||||
/* sleep(HZ/50); no sleeping possible while interrupts are disabled */
|
||||
|
||||
manu = flash[0]; /* read the IDs */
|
||||
id = flash[1];
|
||||
|
||||
flash[0] = 0xF0; /* reset flash (back to normal read mode) */
|
||||
/* Atmel wants 20ms pause here */
|
||||
/* sleep(HZ/50); no sleeping possible while interrupts are disabled */
|
||||
|
||||
restore_irq(old_level); /* enable interrupts again */
|
||||
/* I assume success if the obtained values are different from
|
||||
the normal flash content. This is not perfectly bulletproof, they
|
||||
could theoretically be the same by chance, causing us to fail. */
|
||||
if (not_manu != manu || not_id != id) /* a value has changed */
|
||||
{
|
||||
*p_manufacturer = manu; /* return the results */
|
||||
*p_device = id;
|
||||
return true; /* success */
|
||||
}
|
||||
return false; /* fail */
|
||||
}
|
||||
|
||||
bool dbg_ports(void)
|
||||
{
|
||||
int adc_battery_voltage;
|
||||
#ifndef HAVE_LCD_BITMAP
|
||||
int currval = 0;
|
||||
int button;
|
||||
#else
|
||||
int adc_battery_level;
|
||||
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
#endif
|
||||
lcd_clear_display();
|
||||
|
||||
while(1)
|
||||
{
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
|
||||
lcd_putsf(0, 1, "PBDR: %04x", (unsigned short)PBDR);
|
||||
|
||||
lcd_putsf(0, 2, "AN0: %03x AN4: %03x", adc_read(0), adc_read(4));
|
||||
lcd_putsf(0, 3, "AN1: %03x AN5: %03x", adc_read(1), adc_read(5));
|
||||
lcd_putsf(0, 4, "AN2: %03x AN6: %03x", adc_read(2), adc_read(6));
|
||||
lcd_putsf(0, 5, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7));
|
||||
|
||||
battery_read_info(&adc_battery_voltage, &adc_battery_level);
|
||||
lcd_putsf(0, 6, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000,
|
||||
adc_battery_voltage % 1000, adc_battery_level);
|
||||
|
||||
lcd_update();
|
||||
|
||||
while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
|
||||
|
||||
lcd_setfont(FONT_UI);
|
||||
|
||||
#else /* !HAVE_LCD_BITMAP */
|
||||
|
||||
if (currval == 0) {
|
||||
lcd_putsf(0, 0, "PADR: %04x", (unsigned short)PADR);
|
||||
} else if (currval == 1) {
|
||||
lcd_putsf(0, 0, "PBDR: %04x", (unsigned short)PBDR);
|
||||
} else {
|
||||
int idx = currval - 2; /* idx < 7 */
|
||||
lcd_putsf(0, 0, "AN%d: %03x", idx, adc_read(idx));
|
||||
}
|
||||
|
||||
battery_read_info(&adc_battery_voltage, NULL);
|
||||
lcd_putsf(0, 1, "Batt: %d.%03dV", adc_battery_voltage / 1000,
|
||||
adc_battery_voltage % 1000);
|
||||
lcd_update();
|
||||
|
||||
button = button_get_w_tmo(HZ/5);
|
||||
switch(button)
|
||||
{
|
||||
case BUTTON_STOP:
|
||||
return false;
|
||||
|
||||
case BUTTON_LEFT:
|
||||
currval--;
|
||||
if(currval < 0)
|
||||
currval = 9;
|
||||
break;
|
||||
|
||||
case BUTTON_RIGHT:
|
||||
currval++;
|
||||
if(currval > 9)
|
||||
currval = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dbg_hw_info(void)
|
||||
{
|
||||
#ifndef HAVE_LCD_BITMAP
|
||||
int button;
|
||||
int currval = 0;
|
||||
#else
|
||||
int bitmask = HW_MASK;
|
||||
#endif
|
||||
int rom_version = ROM_VERSION;
|
||||
unsigned manu, id; /* flash IDs */
|
||||
bool got_id; /* flag if we managed to get the flash IDs */
|
||||
unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
|
||||
bool has_bootrom; /* flag for boot ROM present */
|
||||
int oldmode; /* saved memory guard mode */
|
||||
|
||||
oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
|
||||
|
||||
/* get flash ROM type */
|
||||
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
|
||||
if (!got_id)
|
||||
got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
|
||||
|
||||
/* check if the boot ROM area is a flash mirror */
|
||||
has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
|
||||
if (has_bootrom) /* if ROM and Flash different */
|
||||
{
|
||||
/* calculate CRC16 checksum of boot ROM */
|
||||
rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
|
||||
}
|
||||
|
||||
system_memory_guard(oldmode); /* re-enable memory guard */
|
||||
|
||||
lcd_clear_display();
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
lcd_puts(0, 0, "[Hardware info]");
|
||||
|
||||
lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
|
||||
|
||||
lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
|
||||
if (got_id)
|
||||
lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
|
||||
else
|
||||
lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
|
||||
|
||||
if (has_bootrom)
|
||||
{
|
||||
if (rom_crc == 0x56DBA4EE) /* known Version 1 */
|
||||
lcd_puts(0, 4, "Boot ROM: V1");
|
||||
else
|
||||
lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_puts(0, 4, "Boot ROM: none");
|
||||
}
|
||||
|
||||
lcd_update();
|
||||
|
||||
/* wait for exit */
|
||||
while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
|
||||
|
||||
lcd_setfont(FONT_UI);
|
||||
|
||||
#else /* !HAVE_LCD_BITMAP */
|
||||
lcd_puts(0, 0, "[HW Info]");
|
||||
while(1)
|
||||
{
|
||||
switch(currval)
|
||||
{
|
||||
case 0:
|
||||
lcd_putsf(0, 1, "ROM: %d.%02d",
|
||||
rom_version/100, rom_version%100);
|
||||
break;
|
||||
case 1:
|
||||
if (got_id)
|
||||
lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
|
||||
else
|
||||
lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
|
||||
break;
|
||||
case 2:
|
||||
if (has_bootrom)
|
||||
{
|
||||
if (rom_crc == 0x56DBA4EE) /* known Version 1 */
|
||||
lcd_puts(0, 1, "BootROM: V1");
|
||||
else if (rom_crc == 0x358099E8)
|
||||
lcd_puts(0, 1, "BootROM: V2");
|
||||
/* alternative boot ROM found in one single player so far */
|
||||
else
|
||||
lcd_putsf(0, 1, "R: %08x", rom_crc);
|
||||
}
|
||||
else
|
||||
lcd_puts(0, 1, "BootROM: no");
|
||||
}
|
||||
|
||||
lcd_update();
|
||||
|
||||
button = button_get_w_tmo(HZ/10);
|
||||
|
||||
switch(button)
|
||||
{
|
||||
case BUTTON_STOP:
|
||||
return false;
|
||||
|
||||
case BUTTON_LEFT:
|
||||
currval--;
|
||||
if(currval < 0)
|
||||
currval = 2;
|
||||
break;
|
||||
|
||||
case BUTTON_RIGHT:
|
||||
currval++;
|
||||
if(currval > 2)
|
||||
currval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Björn Stenberg
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "panic.h"
|
||||
|
||||
void tick_start(unsigned int interval_in_ms)
|
||||
{
|
||||
unsigned long count;
|
||||
|
||||
count = CPU_FREQ * interval_in_ms / 1000 / 8;
|
||||
|
||||
if(count > 0x10000)
|
||||
{
|
||||
panicf("Error! The tick interval is too long (%d ms)\n",
|
||||
interval_in_ms);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We are using timer 0 */
|
||||
|
||||
TSTR &= ~0x01; /* Stop the timer */
|
||||
TSNC &= ~0x01; /* No synchronization */
|
||||
TMDR &= ~0x01; /* Operate normally */
|
||||
|
||||
TCNT0 = 0; /* Start counting at 0 */
|
||||
GRA0 = (unsigned short)(count - 1);
|
||||
TCR0 = 0x23; /* Clear at GRA match, sysclock/8 */
|
||||
|
||||
/* Enable interrupt on level 1 */
|
||||
IPRC = (IPRC & ~0x00f0) | 0x0010;
|
||||
|
||||
TSR0 &= ~0x01;
|
||||
TIER0 = 0xf9; /* Enable GRA match interrupt */
|
||||
|
||||
TSTR |= 0x01; /* Start timer 1 */
|
||||
}
|
||||
|
||||
void IMIA0(void) __attribute__ ((interrupt_handler));
|
||||
void IMIA0(void)
|
||||
{
|
||||
/* Run through the list of tick tasks */
|
||||
call_tick_tasks();
|
||||
|
||||
TSR0 &= ~0x01;
|
||||
}
|
||||
|
|
@ -1,450 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Based on the work of Alan Korr and others
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "lcd.h"
|
||||
#include "font.h"
|
||||
#include "led.h"
|
||||
|
||||
const unsigned bit_n_table[32] = {
|
||||
1LU<< 0, 1LU<< 1, 1LU<< 2, 1LU<< 3,
|
||||
1LU<< 4, 1LU<< 5, 1LU<< 6, 1LU<< 7,
|
||||
1LU<< 8, 1LU<< 9, 1LU<<10, 1LU<<11,
|
||||
1LU<<12, 1LU<<13, 1LU<<14, 1LU<<15,
|
||||
1LU<<16, 1LU<<17, 1LU<<18, 1LU<<19,
|
||||
1LU<<20, 1LU<<21, 1LU<<22, 1LU<<23,
|
||||
1LU<<24, 1LU<<25, 1LU<<26, 1LU<<27,
|
||||
1LU<<28, 1LU<<29, 1LU<<30, 1LU<<31
|
||||
};
|
||||
|
||||
static const char* const irqname[] = {
|
||||
"", "", "", "", "IllInstr", "", "IllSltIn","","",
|
||||
"CPUAdrEr", "DMAAdrEr", "NMI", "UserBrk",
|
||||
"","","","","","","","","","","","","","","","","","","",
|
||||
"Trap32","Trap33","Trap34","Trap35","Trap36","Trap37","Trap38","Trap39",
|
||||
"Trap40","Trap41","Trap42","Trap43","Trap44","Trap45","Trap46","Trap47",
|
||||
"Trap48","Trap49","Trap50","Trap51","Trap52","Trap53","Trap54","Trap55",
|
||||
"Trap56","Trap57","Trap58","Trap59","Trap60","Trap61","Trap62","Trap63",
|
||||
"Irq0","Irq1","Irq2","Irq3","Irq4","Irq5","Irq6","Irq7",
|
||||
"Dma0","","Dma1","","Dma2","","Dma3","",
|
||||
"IMIA0","IMIB0","OVI0","", "IMIA1","IMIB1","OVI1","",
|
||||
"IMIA2","IMIB2","OVI2","", "IMIA3","IMIB3","OVI3","",
|
||||
"IMIA4","IMIB4","OVI4","",
|
||||
"Ser0Err","Ser0Rx","Ser0Tx","Ser0TE",
|
||||
"Ser1Err","Ser1Rx","Ser1Tx","Ser1TE",
|
||||
"ParityEr","A/D conv","","","Watchdog","DRAMRefr"
|
||||
};
|
||||
|
||||
#define RESERVE_INTERRUPT(number) "\t.long\t_UIE" #number "\n"
|
||||
#define DEFAULT_INTERRUPT(name, number) "\t.weak\t_" #name \
|
||||
"\n\t.set\t_" #name ",_UIE" #number \
|
||||
"\n\t.long\t_" #name "\n"
|
||||
|
||||
asm (
|
||||
|
||||
/* Vector table.
|
||||
* Handled in asm because gcc 4.x doesn't allow weak aliases to symbols
|
||||
* defined in an asm block -- silly.
|
||||
* Reset vectors (0..3) are handled in crt0.S */
|
||||
|
||||
".section\t.vectors,\"aw\",@progbits\n"
|
||||
DEFAULT_INTERRUPT (GII, 4)
|
||||
RESERVE_INTERRUPT ( 5)
|
||||
DEFAULT_INTERRUPT (ISI, 6)
|
||||
RESERVE_INTERRUPT ( 7)
|
||||
RESERVE_INTERRUPT ( 8)
|
||||
DEFAULT_INTERRUPT (CPUAE, 9)
|
||||
DEFAULT_INTERRUPT (DMAAE, 10)
|
||||
DEFAULT_INTERRUPT (NMI, 11)
|
||||
DEFAULT_INTERRUPT (UB, 12)
|
||||
RESERVE_INTERRUPT ( 13)
|
||||
RESERVE_INTERRUPT ( 14)
|
||||
RESERVE_INTERRUPT ( 15)
|
||||
RESERVE_INTERRUPT ( 16) /* TCB #0 */
|
||||
RESERVE_INTERRUPT ( 17) /* TCB #1 */
|
||||
RESERVE_INTERRUPT ( 18) /* TCB #2 */
|
||||
RESERVE_INTERRUPT ( 19) /* TCB #3 */
|
||||
RESERVE_INTERRUPT ( 20) /* TCB #4 */
|
||||
RESERVE_INTERRUPT ( 21) /* TCB #5 */
|
||||
RESERVE_INTERRUPT ( 22) /* TCB #6 */
|
||||
RESERVE_INTERRUPT ( 23) /* TCB #7 */
|
||||
RESERVE_INTERRUPT ( 24) /* TCB #8 */
|
||||
RESERVE_INTERRUPT ( 25) /* TCB #9 */
|
||||
RESERVE_INTERRUPT ( 26) /* TCB #10 */
|
||||
RESERVE_INTERRUPT ( 27) /* TCB #11 */
|
||||
RESERVE_INTERRUPT ( 28) /* TCB #12 */
|
||||
RESERVE_INTERRUPT ( 29) /* TCB #13 */
|
||||
RESERVE_INTERRUPT ( 30) /* TCB #14 */
|
||||
RESERVE_INTERRUPT ( 31) /* TCB #15 */
|
||||
DEFAULT_INTERRUPT (TRAPA32, 32)
|
||||
DEFAULT_INTERRUPT (TRAPA33, 33)
|
||||
DEFAULT_INTERRUPT (TRAPA34, 34)
|
||||
DEFAULT_INTERRUPT (TRAPA35, 35)
|
||||
DEFAULT_INTERRUPT (TRAPA36, 36)
|
||||
DEFAULT_INTERRUPT (TRAPA37, 37)
|
||||
DEFAULT_INTERRUPT (TRAPA38, 38)
|
||||
DEFAULT_INTERRUPT (TRAPA39, 39)
|
||||
DEFAULT_INTERRUPT (TRAPA40, 40)
|
||||
DEFAULT_INTERRUPT (TRAPA41, 41)
|
||||
DEFAULT_INTERRUPT (TRAPA42, 42)
|
||||
DEFAULT_INTERRUPT (TRAPA43, 43)
|
||||
DEFAULT_INTERRUPT (TRAPA44, 44)
|
||||
DEFAULT_INTERRUPT (TRAPA45, 45)
|
||||
DEFAULT_INTERRUPT (TRAPA46, 46)
|
||||
DEFAULT_INTERRUPT (TRAPA47, 47)
|
||||
DEFAULT_INTERRUPT (TRAPA48, 48)
|
||||
DEFAULT_INTERRUPT (TRAPA49, 49)
|
||||
DEFAULT_INTERRUPT (TRAPA50, 50)
|
||||
DEFAULT_INTERRUPT (TRAPA51, 51)
|
||||
DEFAULT_INTERRUPT (TRAPA52, 52)
|
||||
DEFAULT_INTERRUPT (TRAPA53, 53)
|
||||
DEFAULT_INTERRUPT (TRAPA54, 54)
|
||||
DEFAULT_INTERRUPT (TRAPA55, 55)
|
||||
DEFAULT_INTERRUPT (TRAPA56, 56)
|
||||
DEFAULT_INTERRUPT (TRAPA57, 57)
|
||||
DEFAULT_INTERRUPT (TRAPA58, 58)
|
||||
DEFAULT_INTERRUPT (TRAPA59, 59)
|
||||
DEFAULT_INTERRUPT (TRAPA60, 60)
|
||||
DEFAULT_INTERRUPT (TRAPA61, 61)
|
||||
DEFAULT_INTERRUPT (TRAPA62, 62)
|
||||
DEFAULT_INTERRUPT (TRAPA63, 63)
|
||||
DEFAULT_INTERRUPT (IRQ0, 64)
|
||||
DEFAULT_INTERRUPT (IRQ1, 65)
|
||||
DEFAULT_INTERRUPT (IRQ2, 66)
|
||||
DEFAULT_INTERRUPT (IRQ3, 67)
|
||||
DEFAULT_INTERRUPT (IRQ4, 68)
|
||||
DEFAULT_INTERRUPT (IRQ5, 69)
|
||||
DEFAULT_INTERRUPT (IRQ6, 70)
|
||||
DEFAULT_INTERRUPT (IRQ7, 71)
|
||||
DEFAULT_INTERRUPT (DEI0, 72)
|
||||
RESERVE_INTERRUPT ( 73)
|
||||
DEFAULT_INTERRUPT (DEI1, 74)
|
||||
RESERVE_INTERRUPT ( 75)
|
||||
DEFAULT_INTERRUPT (DEI2, 76)
|
||||
RESERVE_INTERRUPT ( 77)
|
||||
DEFAULT_INTERRUPT (DEI3, 78)
|
||||
RESERVE_INTERRUPT ( 79)
|
||||
DEFAULT_INTERRUPT (IMIA0, 80)
|
||||
DEFAULT_INTERRUPT (IMIB0, 81)
|
||||
DEFAULT_INTERRUPT (OVI0, 82)
|
||||
RESERVE_INTERRUPT ( 83)
|
||||
DEFAULT_INTERRUPT (IMIA1, 84)
|
||||
DEFAULT_INTERRUPT (IMIB1, 85)
|
||||
DEFAULT_INTERRUPT (OVI1, 86)
|
||||
RESERVE_INTERRUPT ( 87)
|
||||
DEFAULT_INTERRUPT (IMIA2, 88)
|
||||
DEFAULT_INTERRUPT (IMIB2, 89)
|
||||
DEFAULT_INTERRUPT (OVI2, 90)
|
||||
RESERVE_INTERRUPT ( 91)
|
||||
DEFAULT_INTERRUPT (IMIA3, 92)
|
||||
DEFAULT_INTERRUPT (IMIB3, 93)
|
||||
DEFAULT_INTERRUPT (OVI3, 94)
|
||||
RESERVE_INTERRUPT ( 95)
|
||||
DEFAULT_INTERRUPT (IMIA4, 96)
|
||||
DEFAULT_INTERRUPT (IMIB4, 97)
|
||||
DEFAULT_INTERRUPT (OVI4, 98)
|
||||
RESERVE_INTERRUPT ( 99)
|
||||
DEFAULT_INTERRUPT (REI0, 100)
|
||||
DEFAULT_INTERRUPT (RXI0, 101)
|
||||
DEFAULT_INTERRUPT (TXI0, 102)
|
||||
DEFAULT_INTERRUPT (TEI0, 103)
|
||||
DEFAULT_INTERRUPT (REI1, 104)
|
||||
DEFAULT_INTERRUPT (RXI1, 105)
|
||||
DEFAULT_INTERRUPT (TXI1, 106)
|
||||
DEFAULT_INTERRUPT (TEI1, 107)
|
||||
RESERVE_INTERRUPT ( 108)
|
||||
DEFAULT_INTERRUPT (ADITI, 109)
|
||||
|
||||
/* UIE# block.
|
||||
* Must go into the same section as the UIE() handler */
|
||||
|
||||
"\t.text\n"
|
||||
"_UIE4:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE5:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE6:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE7:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE8:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE9:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE10:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE11:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE12:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE13:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE14:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE15:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE16:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE17:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE18:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE19:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE20:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE21:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE22:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE23:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE24:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE25:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE26:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE27:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE28:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE29:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE30:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE31:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE32:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE33:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE34:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE35:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE36:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE37:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE38:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE39:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE40:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE41:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE42:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE43:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE44:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE45:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE46:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE47:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE48:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE49:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE50:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE51:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE52:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE53:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE54:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE55:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE56:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE57:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE58:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE59:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE60:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE61:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE62:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE63:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE64:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE65:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE66:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE67:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE68:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE69:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE70:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE71:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE72:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE73:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE74:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE75:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE76:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE77:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE78:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE79:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE80:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE81:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE82:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE83:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE84:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE85:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE86:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE87:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE88:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE89:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE90:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE91:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE92:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE93:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE94:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE95:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE96:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE97:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE98:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE99:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE100:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE101:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE102:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE103:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE104:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE105:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE106:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE107:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE108:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
"_UIE109:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
|
||||
|
||||
);
|
||||
|
||||
extern void UIE4(void); /* needed for calculating the UIE number */
|
||||
|
||||
void UIE (unsigned int pc) __attribute__((section(".text")));
|
||||
void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
asm volatile ("sts\tpr,%0" : "=r"(n));
|
||||
|
||||
/* clear screen */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#if LCD_DEPTH > 1
|
||||
lcd_set_backdrop(NULL);
|
||||
lcd_set_drawmode(DRMODE_SOLID);
|
||||
lcd_set_foreground(LCD_BLACK);
|
||||
lcd_set_background(LCD_WHITE);
|
||||
#endif
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
lcd_set_viewport(NULL);
|
||||
#endif
|
||||
|
||||
lcd_clear_display();
|
||||
/* output exception */
|
||||
n = (n - (unsigned)UIE4 + 12)>>2; /* get exception or interrupt number */
|
||||
lcd_putsf(0, 0, "I%02x:%s", n, irqname[n]);
|
||||
lcd_putsf(0, 1, "at %08x", pc);
|
||||
lcd_update();
|
||||
|
||||
/* try to restart firmware if ON is pressed */
|
||||
system_exception_wait();
|
||||
|
||||
/* enable the watchguard timer, but don't service it */
|
||||
RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
|
||||
TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
|
||||
while (1);
|
||||
}
|
||||
|
||||
void system_init(void)
|
||||
{
|
||||
/* Disable all interrupts */
|
||||
IPRA = 0;
|
||||
IPRB = 0;
|
||||
IPRC = 0;
|
||||
IPRD = 0;
|
||||
IPRE = 0;
|
||||
|
||||
/* NMI level low, falling edge on all interrupts */
|
||||
ICR = 0;
|
||||
|
||||
/* Enable burst and RAS down mode on DRAM */
|
||||
DCR |= 0x5000;
|
||||
|
||||
/* Activate Warp mode (simultaneous internal and external mem access) */
|
||||
BCR |= 0x2000;
|
||||
|
||||
/* Bus state controller initializations. These are only necessary when
|
||||
running from flash. */
|
||||
WCR1 = 0x40FD; /* Long wait states for CS6 (ATA), short for the rest. */
|
||||
WCR3 = 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */
|
||||
}
|
||||
|
||||
void system_reboot (void)
|
||||
{
|
||||
disable_irq();
|
||||
|
||||
asm volatile ("ldc\t%0,vbr" : : "r"(0));
|
||||
|
||||
PACR2 |= 0x4000; /* for coldstart detection */
|
||||
IPRA = 0;
|
||||
IPRB = 0;
|
||||
IPRC = 0;
|
||||
IPRD = 0;
|
||||
IPRE = 0;
|
||||
ICR = 0;
|
||||
|
||||
asm volatile ("jmp @%0; mov.l @%1,r15" : :
|
||||
"r"(*(int*)0),"r"(4));
|
||||
}
|
||||
|
||||
void system_exception_wait(void)
|
||||
{
|
||||
#if (CONFIG_LED == LED_REAL)
|
||||
bool state = false;
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
#if (CONFIG_LED == LED_REAL)
|
||||
if (--i <= 0)
|
||||
{
|
||||
state = !state;
|
||||
led(state);
|
||||
i = 240000;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_KEYPAD == PLAYER_PAD
|
||||
/* Player */
|
||||
if (!(PADRL & 0x20))
|
||||
#elif CONFIG_KEYPAD == RECORDER_PAD
|
||||
/* Recorder */
|
||||
#ifdef HAVE_FMADC
|
||||
if (!(PCDR & 0x0008))
|
||||
#else
|
||||
if (!(PBDRH & 0x01))
|
||||
#endif
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
/* Ondio */
|
||||
if (!(PCDR & 0x0008))
|
||||
#endif /* CONFIG_KEYPAD */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Utilise the user break controller to catch invalid memory accesses. */
|
||||
int system_memory_guard(int newmode)
|
||||
{
|
||||
static const struct {
|
||||
unsigned long addr;
|
||||
unsigned long mask;
|
||||
unsigned short bbr;
|
||||
} modes[MAXMEMGUARD] = {
|
||||
/* catch nothing */
|
||||
{ 0x00000000, 0x00000000, 0x0000 },
|
||||
/* catch writes to area 02 (flash ROM) */
|
||||
{ 0x02000000, 0x00FFFFFF, 0x00F8 },
|
||||
/* catch all accesses to areas 00 (internal ROM) and 01 (free) */
|
||||
{ 0x00000000, 0x01FFFFFF, 0x00FC }
|
||||
};
|
||||
|
||||
int oldmode = MEMGUARD_NONE;
|
||||
int i;
|
||||
|
||||
/* figure out the old mode from what is in the UBC regs. If the register
|
||||
values don't match any mode, assume MEMGUARD_NONE */
|
||||
for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
|
||||
{
|
||||
if (BAR == modes[i].addr && BAMR == modes[i].mask &&
|
||||
BBR == modes[i].bbr)
|
||||
{
|
||||
oldmode = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newmode == MEMGUARD_KEEP)
|
||||
newmode = oldmode;
|
||||
|
||||
BBR = 0; /* switch off everything first */
|
||||
|
||||
/* always set the UBC according to the mode, in case the old settings
|
||||
didn't match any valid mode */
|
||||
BAR = modes[newmode].addr;
|
||||
BAMR = modes[newmode].mask;
|
||||
BBR = modes[newmode].bbr;
|
||||
|
||||
return oldmode;
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Jens Arnold
|
||||
* Based on the work of Alan Korr and others
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef SYSTEM_TARGET_H
|
||||
#define SYSTEM_TARGET_H
|
||||
|
||||
#define or_b(mask, address) \
|
||||
asm \
|
||||
("or.b %0,@(r0,gbr)" \
|
||||
: \
|
||||
: /* %0 */ I_CONSTRAINT((char)(mask)), \
|
||||
/* %1 */ "z"(address-GBR))
|
||||
|
||||
#define and_b(mask, address) \
|
||||
asm \
|
||||
("and.b %0,@(r0,gbr)" \
|
||||
: \
|
||||
: /* %0 */ I_CONSTRAINT((char)(mask)), \
|
||||
/* %1 */ "z"(address-GBR))
|
||||
|
||||
#define xor_b(mask, address) \
|
||||
asm \
|
||||
("xor.b %0,@(r0,gbr)" \
|
||||
: \
|
||||
: /* %0 */ I_CONSTRAINT((char)(mask)), \
|
||||
/* %1 */ "z"(address-GBR))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Interrupt level setting
|
||||
* The level is left shifted 4 bits
|
||||
****************************************************************************/
|
||||
#define HIGHEST_IRQ_LEVEL (15<<4)
|
||||
|
||||
static inline int set_irq_level(int level)
|
||||
{
|
||||
int i;
|
||||
/* Read the old level and set the new one */
|
||||
|
||||
/* Not volatile - will be optimized away if the return value isn't used */
|
||||
asm ("stc sr, %0" : "=r" (i));
|
||||
asm volatile ("ldc %0, sr" : : "r" (level));
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline void enable_irq(void)
|
||||
{
|
||||
int i;
|
||||
asm volatile ("mov %1, %0 \n" /* Save a constant load from RAM */
|
||||
"ldc %0, sr \n" : "=&r"(i) : "i"(0));
|
||||
}
|
||||
|
||||
#define disable_irq() \
|
||||
((void)set_irq_level(HIGHEST_IRQ_LEVEL))
|
||||
|
||||
#define disable_irq_save() \
|
||||
set_irq_level(HIGHEST_IRQ_LEVEL)
|
||||
|
||||
#define restore_irq(i) \
|
||||
((void)set_irq_level(i))
|
||||
|
||||
static inline uint16_t swap16_hw(uint16_t value)
|
||||
/*
|
||||
result[15..8] = value[ 7..0];
|
||||
result[ 7..0] = value[15..8];
|
||||
*/
|
||||
{
|
||||
uint16_t result;
|
||||
asm ("swap.b\t%1,%0" : "=r"(result) : "r"(value));
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t swaw32_hw(uint32_t value)
|
||||
/*
|
||||
result[31..16] = value[15.. 0];
|
||||
result[15.. 0] = value[31..16];
|
||||
*/
|
||||
{
|
||||
uint32_t result;
|
||||
asm ("swap.w\t%1,%0" : "=r"(result) : "r"(value));
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t swap32_hw(uint32_t value)
|
||||
/*
|
||||
result[31..24] = value[ 7.. 0];
|
||||
result[23..16] = value[15.. 8];
|
||||
result[15.. 8] = value[23..16];
|
||||
result[ 7.. 0] = value[31..24];
|
||||
*/
|
||||
{
|
||||
asm ("swap.b\t%0,%0\n"
|
||||
"swap.w\t%0,%0\n"
|
||||
"swap.b\t%0,%0\n" : "+r"(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline uint32_t swap_odd_even32_hw(uint32_t value)
|
||||
{
|
||||
/*
|
||||
result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
|
||||
result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
|
||||
*/
|
||||
asm ("swap.b\t%0,%0\n"
|
||||
"swap.w\t%0,%0\n"
|
||||
"swap.b\t%0,%0\n"
|
||||
"swap.w\t%0,%0\n" : "+r"(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
extern const unsigned bit_n_table[32];
|
||||
#define BIT_N(n) ( \
|
||||
__builtin_constant_p(n) \
|
||||
? (1U << (n)) \
|
||||
: bit_n_table[n] \
|
||||
)
|
||||
|
||||
static inline void commit_dcache(void) {}
|
||||
static inline void commit_discard_dcache(void) {}
|
||||
static inline void commit_discard_idcache(void) {}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Put core in a power-saving state.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static inline void core_sleep(void)
|
||||
{
|
||||
asm volatile (
|
||||
"and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
|
||||
"mov #0, r1 \n" /* Enable interrupts */
|
||||
"ldc r1, sr \n" /* Following instruction cannot be interrupted */
|
||||
"sleep \n" /* Execute standby */
|
||||
: : "z"(&SBYCR-GBR) : "r1");
|
||||
}
|
||||
|
||||
#endif /* SYSTEM_TARGET_H */
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
FIRMWARE=../..
|
||||
|
||||
CC ?= gcc
|
||||
# Note: Don't be fooled by MEMORYSIZE here
|
||||
# We have a fixed, predictable buffer in UT_core_allocator_init()
|
||||
CFLAGS += -g -O2 -DDEBUG -D__PCTOOL__ -DBUFLIB_UNIT_TEST -DMEMORYSIZE=8 -DBUFLIB_DEBUG_BLOCKS -std=gnu99 -I$(FIRMWARE)/include -I$(FIRMWARE)/export -I.
|
||||
LDFLAGS += -L. -lpthread
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
TARGETS_OBJ = test_main.o \
|
||||
test_main2.o \
|
||||
test_move.o \
|
||||
test_move2.o \
|
||||
test_max.o \
|
||||
test_shrink.o \
|
||||
test_shrink_unaligned.o \
|
||||
test_shrink_startchanged.o \
|
||||
test_shrink_cb.o
|
||||
|
||||
TARGETS = $(TARGETS_OBJ:.o=)
|
||||
|
||||
LIB_OBJ = buflib.o \
|
||||
core_alloc.o \
|
||||
crc32.o \
|
||||
strlcpy.o \
|
||||
util.o
|
||||
|
||||
LIB_FILE = libbuflib.a
|
||||
LIB = buflib
|
||||
|
||||
|
||||
ifndef V
|
||||
SILENT:=@
|
||||
else
|
||||
VERBOSEOPT:=-v
|
||||
endif
|
||||
|
||||
PRINTS=$(SILENT)$(call info,$(1))
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
test_%: test_%.o $(LIB_FILE)
|
||||
$(call PRINTS,LD $@)$(CC) $(LDFLAGS) -o $@ $< -l$(LIB)
|
||||
|
||||
$(TARGETS): $(TARGETS_OBJ) $(LIB_FILE)
|
||||
|
||||
buflib.o: $(FIRMWARE)/buflib.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
core_alloc.o: $(FIRMWARE)/core_alloc.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
crc32.o: $(FIRMWARE)/common/crc32.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
strlcpy.o: $(FIRMWARE)/common/strlcpy.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.c
|
||||
$(call PRINTS,CC $<)$(CC) $(CFLAGS) -c $<
|
||||
|
||||
$(LIB_FILE): $(LIB_OBJ)
|
||||
$(call PRINTS,AR $@)ar rcs $@ $^
|
||||
|
||||
clean:
|
||||
rm *.o $(TARGETS) $(LIB_FILE)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/* Define endianess for the target or simulator platform */
|
||||
#define ROCKBOX_LITTLE_ENDIAN 1
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2015 Thomas Jarosch
|
||||
*
|
||||
* Loosely based upon rbcodecplatform-unix.h from rbcodec
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _COMMON_UNITTEST_H
|
||||
#define _COMMON_UNITTEST_H
|
||||
|
||||
/* debugf, logf */
|
||||
#define debugf(...) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
#ifndef logf
|
||||
#define logf(...) do { fprintf(stderr, __VA_ARGS__); \
|
||||
putc('\n', stderr); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef panicf
|
||||
#define panicf(...) do { fprintf(stderr, __VA_ARGS__); \
|
||||
putc('\n', stderr); \
|
||||
exit(-1); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _COMMON_UNITTEST_H */
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Thomas Martitz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "buflib.h"
|
||||
#include "util.h"
|
||||
|
||||
#define BUFLIB_BUFFER_SIZE (12<<10)
|
||||
static char buflib_buffer[BUFLIB_BUFFER_SIZE];
|
||||
static struct buflib_context ctx;
|
||||
#define assert(x) do { if (!(x)) exit(1); } while(0)
|
||||
|
||||
int move_callback(int handle, void* current, void* new)
|
||||
{
|
||||
(void)handle;(void)current;(void)new;
|
||||
printf("Move!\n");
|
||||
}
|
||||
|
||||
int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
|
||||
{
|
||||
(void)handle;(void)start;(void)old_size;(void)hints;
|
||||
printf("Shrink");
|
||||
}
|
||||
|
||||
struct buflib_callbacks ops = {
|
||||
.move_callback = move_callback,
|
||||
.shrink_callback = shrink_callback,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
buflib_init(&ctx, buflib_buffer, BUFLIB_BUFFER_SIZE);
|
||||
|
||||
int id = buflib_alloc_ex(&ctx, 512, "foo", &ops);
|
||||
int id2 = buflib_alloc_ex(&ctx, 1024, "bar", &ops);
|
||||
int id3 = buflib_alloc_ex(&ctx, 8<<10, "8K", &ops);
|
||||
|
||||
assert(id > 0 && id2 > 0 && id3 > 0);
|
||||
|
||||
#define STR "<TEST>"
|
||||
strncpy(buflib_get_data(&ctx, id3), STR, sizeof STR);
|
||||
if (id > 0)
|
||||
{
|
||||
buflib_print_allocs(&ctx, &print_handle);
|
||||
buflib_free(&ctx, id);
|
||||
buflib_print_allocs(&ctx, &print_handle);
|
||||
buflib_free(&ctx, id2);
|
||||
buflib_print_allocs(&ctx, &print_handle);
|
||||
|
||||
id = buflib_alloc_ex(&ctx, 3<<10, "should compact", &ops);
|
||||
if (id <= 0) printf("compacting alloc failed\n");
|
||||
|
||||
buflib_print_allocs(&ctx, &print_handle);
|
||||
|
||||
printf("id I: %p\n", buflib_get_data(&ctx, id3));
|
||||
id2 = buflib_alloc_ex(&ctx, 3<<10, "should fail", &ops);
|
||||
printf("id II: %p\n", buflib_get_data(&ctx, id3));
|
||||
if (id2 <= 0) printf("failing alloc failed\n");
|
||||
else buflib_free(&ctx, id2);
|
||||
|
||||
if (id > 0)
|
||||
buflib_free(&ctx, id);
|
||||
|
||||
printf("Check string: \"%s\"\n", buflib_get_data(&ctx, id3));
|
||||
buflib_print_allocs(&ctx, &print_handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue