diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c index 4537c4b..7aa62d1 100644 --- a/bootloader/sansa_as3525.c +++ b/bootloader/sansa_as3525.c @@ -50,12 +50,17 @@ void main(void) /* stop here */ while(1); #endif + lcd_init(); show_logo(); - ascodec_init(); /* Required for backlight on e200v2 */ + ascodec_init(); /* required for e200v2 backlight & clipv2 OLED */ _backlight_on(); +#ifdef SANSA_CLIPV2 + while(1); /* stop here */ +#endif + button_init_device(); int btn = button_read_device(); diff --git a/bootloader/show_logo.c b/bootloader/show_logo.c index c0627aa..90cf222 100644 --- a/bootloader/show_logo.c +++ b/bootloader/show_logo.c @@ -41,7 +41,7 @@ int show_logo( void ) lcd_clear_display(); lcd_setfont(FONT_SYSFIXED); -#ifdef SANSA_CLIP +#if defined(SANSA_CLIP) || defined(SANSA_CLIPV2) /* The top 16 lines of the Sansa Clip screen are yellow, and the bottom 48 are blue, so we reverse the usual positioning */ lcd_putsxy(TEXT_XPOS, 0, BOOT_VERSION); diff --git a/firmware/SOURCES b/firmware/SOURCES index 98569c4..6edc005 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1092,6 +1092,19 @@ target/arm/pcm-telechips.c #endif /* SIMULATOR */ #endif /* SANSA_C100 */ +#ifdef SANSA_CLIPV2 +#ifndef SIMULATOR +target/arm/as3525/sansa-clipv2/lcd-ssd1303.c +target/arm/as3525/sansa-clipv2/lcd-as-clip.S +target/arm/as3525/sansa-clipv2/button-clip.c +target/arm/as3525/sansa-clipv2/backlight-clip.c +#ifndef BOOTLOADER +target/arm/powermgmt-ascodec.c +target/arm/as3525/sansa-clip/powermgmt-clip.c +#endif /* !BOOTLOADER */ +#endif /* !SIMULATOR */ +#endif /* SANSA_CLIPV2 */ + #ifdef SANSA_CLIP #ifndef SIMULATOR target/arm/as3525/sansa-clip/lcd-ssd1303.c diff --git a/firmware/export/config-clip.h b/firmware/export/config-clip.h index 9ebd3ec..6001b53 100644 --- a/firmware/export/config-clip.h +++ b/firmware/export/config-clip.h @@ -122,7 +122,7 @@ #define AB_REPEAT_ENABLE 1 /* FM Tuner */ -#define CONFIG_TUNER SI4700 /* in fact SI4702 but let's hope it's compatible */ +#define CONFIG_TUNER SI4700 /* in fact SI4702 */ //#define HAVE_TUNER_PWR_CTRL /* Define this for LCD backlight available */ diff --git a/firmware/export/config-clipv2.h b/firmware/export/config-clipv2.h new file mode 100644 index 0000000..0beca4b --- /dev/null +++ b/firmware/export/config-clipv2.h @@ -0,0 +1,215 @@ +/* + * This config file is for the Sandisk Sansa Clip v2 + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 46 +#define MODEL_NAME "Sandisk Sansa Clipv2" +#define FIRMWARE_OFFSET_FILE_DATA 8 +#define FIRMWARE_OFFSET_FILE_CRC 0 + +#if 0 /* disabled since there is no driver (yet) */ + +#define HW_SAMPR_CAPS (SAMPR_CAP_44) + +/* define this if you have recording possibility */ +#define HAVE_RECORDING + +#define REC_SAMPR_CAPS (SAMPR_CAP_22) +#define REC_FREQ_DEFAULT REC_FREQ_22 /* Default is not 44.1kHz */ +#define REC_SAMPR_DEFAULT SAMPR_22 + +#endif + +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_FMRADIO) + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you have a light associated with the buttons */ +#define HAVE_BUTTON_LIGHT + +/* define this if you have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you have access to the pitchscreen */ +#define HAVE_PITCHSCREEN + +/* define this if you would like tagcache to build on this target */ +#define HAVE_TAGCACHE + +/* LCD dimensions */ +#define LCD_WIDTH 128 +#define LCD_HEIGHT 64 +#define LCD_DEPTH 1 + +#define LCD_PIXELFORMAT VERTICAL_PACKING +#define HAVE_NEGATIVE_LCD /* bright on dark */ +#define HAVE_LCD_SPLIT /* split display */ + +/* Display colours, for screenshots and sim (0xRRGGBB) */ +#define LCD_DARKCOLOR 0x000000 +#define LCD_BRIGHTCOLOR 0x000000 +#define LCD_BL_DARKCOLOR 0x000000 +#define LCD_BL_BRIGHTCOLOR 0x0de2e5 + +#define LCD_DARKCOLOR_2 0x000000 +#define LCD_BRIGHTCOLOR_2 0x000000 +#define LCD_BL_DARKCOLOR_2 0x000000 +#define LCD_BL_BRIGHTCOLOR_2 0xffe60f + +#define LCD_SPLIT_POS 16 +#define LCD_SPLIT_LINES 2 + +/* define this if you have LCD enable function */ +#define HAVE_LCD_ENABLE + +#ifndef BOOTLOADER +/* Define this if your LCD can be put to sleep. + * HAVE_LCD_ENABLE should be defined as well. */ +//#define HAVE_LCD_SLEEP +//#define HAVE_LCD_SLEEP_SETTING +#endif + +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + +/* define this if you can invert the pixels */ +#define HAVE_LCD_INVERT + +/* Define this if your LCD can set contrast */ +#define HAVE_LCD_CONTRAST + +#define MIN_CONTRAST_SETTING 0 +#define MAX_CONTRAST_SETTING 50 +#define DEFAULT_CONTRAST_SETTING 30 + +#define IRAM_LCDFRAMEBUFFER IDATA_ATTR /* put the lcd frame buffer in IRAM */ + +#define CONFIG_KEYPAD SANSA_CLIP_PAD + +/* define this if the target has volume keys which can be used in the lists */ +#define HAVE_VOLUME_IN_LIST + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC +/* There is no hardware tone control */ +#define HAVE_SW_TONE_CONTROLS + +/* We're working on the assumption that the AS3525 has something + similar to the AS3514 for audio codec etc */ +#define HAVE_AS3514 + +/* define this if you have a real-time clock */ +#ifndef BOOTLOADER +#define CONFIG_RTC RTC_AS3514 +#endif + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +#define HAVE_FAT16SUPPORT + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x100000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x80000 + +#define AB_REPEAT_ENABLE 1 + +/* FM Tuner */ +#define CONFIG_TUNER SI4700 /* in fact SI4702 */ +//#define HAVE_TUNER_PWR_CTRL + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT + +/* define this if you have a flash memory storage */ +#define HAVE_FLASH_STORAGE + +/* define this if the flash memory uses the SecureDigital Memory Card protocol */ +#define CONFIG_STORAGE STORAGE_SD + +#define BATTERY_CAPACITY_DEFAULT 380 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 380 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 380 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 0 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* Charging implemented in a target-specific algorithm */ +#define CONFIG_CHARGING CHARGING_TARGET + +/* define this if the unit can be powered or charged via USB */ +#define HAVE_USB_POWER + +/** Non-simulator section **/ +#ifndef SIMULATOR + +/* Define this if you have a AMS AS3525 SoC */ +#define CONFIG_CPU AS3525 /* FIXME: AS3531? */ + +/* Define this if you want to use the AS3525 i2c interface */ +#define CONFIG_I2C I2C_AS3525 + +/* define this if the hardware can be powered off while charging */ +/* Sansa can't be powered off while charging */ +/* #define HAVE_POWEROFF_WHILE_CHARGING */ + +/* The start address index for ROM builds */ +#define ROM_START 0x00000000 + +/* Define this to the CPU frequency */ +#define CPU_FREQ 250000000 + +/* Type of LCD */ +#define CONFIG_LCD LCD_SSD1303 + +#ifndef BOOTLOADER + +#define USB_HANDLED_BY_OF + +#if 0 /* disabled since there is no USB driver */ + +/* USB On-the-go */ +#define CONFIG_USBOTG USBOTG_ARC + +/* enable these for the experimental usb stack */ +#define HAVE_USBSTACK +#define USB_VENDOR_ID 0x0781 +#define USB_PRODUCT_ID 0x7433 +#endif /* BOOTLOADER */ + +#endif + + +/* Virtual LED (icon) */ +#define CONFIG_LED LED_VIRTUAL + +/* Define this if you have adjustable CPU frequency */ +#define HAVE_ADJUSTABLE_CPU_FREQ + +#define BOOTFILE_EXT "sansa" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/.rockbox" + +#define ICODE_ATTR_TREMOR_NOT_MDCT + +#define INCLUDE_TIMEOUT_API + +#endif /* SIMULATOR */ + +/** Port-specific settings **/ + +/* Main LCD backlight brightness range and defaults */ +#define MIN_BRIGHTNESS_SETTING 1 +#define MAX_BRIGHTNESS_SETTING 12 +#define DEFAULT_BRIGHTNESS_SETTING 6 + +/* Default recording levels */ +#define DEFAULT_REC_MIC_GAIN 23 +#define DEFAULT_REC_LEFT_GAIN 23 +#define DEFAULT_REC_RIGHT_GAIN 23 diff --git a/firmware/export/config.h b/firmware/export/config.h index 7680a9f..7e31b24 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -348,6 +348,8 @@ #include "config-ondavx767.h" #elif defined(SANSA_CLIP) #include "config-clip.h" +#elif defined(SANSA_CLIPV2) +#include "config-clipv2.h" #elif defined(SANSA_E200V2) #include "config-e200v2.h" #elif defined(SANSA_M200V4) @@ -577,14 +579,13 @@ #if (CONFIG_CPU == IMX31L) #define CPU_ARM #define ARM_ARCH 6 /* ARMv6 */ -#endif -#if defined(CPU_TCC77X) || defined(CPU_TCC780X) || (CONFIG_CPU == DM320) +#elif defined(CPU_TCC77X) || defined(CPU_TCC780X) || (CONFIG_CPU == DM320) \ + || defined(SANSA_CLIPV2) #define CPU_ARM #define ARM_ARCH 5 /* ARMv5 */ -#endif -#if defined(CPU_PP) || (CONFIG_CPU == PNX0101) || (CONFIG_CPU == S3C2440) \ +#elif defined(CPU_PP) || (CONFIG_CPU == PNX0101) || (CONFIG_CPU == S3C2440) \ || (CONFIG_CPU == DSC25) || (CONFIG_CPU == S5L8700) || (CONFIG_CPU == AS3525) #define CPU_ARM #define ARM_ARCH 4 /* ARMv4 */ diff --git a/firmware/target/arm/as3525/app.lds b/firmware/target/arm/as3525/app.lds index 09844a1..b6accf7 100644 --- a/firmware/target/arm/as3525/app.lds +++ b/firmware/target/arm/as3525/app.lds @@ -32,8 +32,13 @@ STARTUP(target/arm/crt0.o) #define CODECORIG (ENDAUDIOADDR) #endif +#if defined(SANSA_CLIPV2) +#define IRAMORIG 0x81000000 +#define DRAMORIG 0x0 + STUBOFFSET +#else #define IRAMORIG 0x0 #define DRAMORIG 0x30000000 + STUBOFFSET +#endif /* End of the audio buffer, where the codec buffer starts */ #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) @@ -58,7 +63,23 @@ MEMORY SECTIONS { +#if defined(SANSA_CLIPV2) + loadaddress = 0x0; +#else loadaddress = 0x30000000; +#endif + + .vectors 0x0: + { + _vectors_start = .; + *(.init.text) +#if defined(SANSA_CLIPV2) + } > DRAM +#else + } > IRAM AT > DRAM + + _vectorscopy = LOADADDR(.vectors); +#endif .text : { @@ -91,14 +112,6 @@ SECTIONS *(.eh_frame) } - .vectors IRAMORIG: - { - _vectors_start = .; - *(.init.text) - } > IRAM AT > DRAM - - _vectorscopy = LOADADDR(.vectors); - .iram : { _iramstart = .; diff --git a/firmware/target/arm/as3525/boot.lds b/firmware/target/arm/as3525/boot.lds index 7a13d67..95199f2 100644 --- a/firmware/target/arm/as3525/boot.lds +++ b/firmware/target/arm/as3525/boot.lds @@ -5,27 +5,29 @@ OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/crt0.o) -#define DRAMSIZE (MEMORYSIZE * 0x100000) -#define DRAMORIG 0x30000000 -#define IRAMORIG 0 -#define IRAMSIZE 0x50000 +#define RAMORIG 0 + +#ifdef SANSA_CLIPV2 /* DRAM is mapped at 0 */ +#define RAMSIZE (MEM*0x100000 - RAMORIG) +#else /* RAM is mapped at 0 */ +#define RAMSIZE 0x50000 +#endif MEMORY { - DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE - IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE + RAM : ORIGIN = RAMORIG, LENGTH = RAMSIZE } SECTIONS { - . = IRAMORIG; + . = RAMORIG; .text : { *(.init.text) *(.glue_7) *(.glue_7t) *(.text*) - } > IRAM + } > RAM .data : { *(.icode) @@ -35,7 +37,7 @@ SECTIONS *(.ncdata*) *(.rodata*) _dataend = . ; - } > IRAM + } > RAM .stack : { @@ -45,7 +47,7 @@ SECTIONS . += 0x2000; _stackend = .; stackend = .; - } > IRAM + } > RAM .bss : { _edata = .; @@ -54,5 +56,5 @@ SECTIONS *(COMMON) *(.ncbss*); _end = .; - } > IRAM + } > RAM } diff --git a/firmware/target/arm/as3525/clock-target.h b/firmware/target/arm/as3525/clock-target.h index a227f46..312b4d5 100644 --- a/firmware/target/arm/as3525/clock-target.h +++ b/firmware/target/arm/as3525/clock-target.h @@ -48,7 +48,7 @@ #define AS3525_I2C_FREQ 400000 /* LCD controller : varies on the models */ -#if defined(SANSA_CLIP) +#if defined(SANSA_CLIP) || defined(SANSA_CLIPV2) #define AS3525_DBOP_FREQ 6000000 #elif defined(SANSA_M200V4) #define AS3525_DBOP_FREQ 8000000 diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c index 528e8c7..08e10d8 100644 --- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c +++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c @@ -37,6 +37,12 @@ #define I2C_SCL_PIN 4 #define I2C_SDA_PIN 5 +#elif defined(SANSA_CLIPV2) +#define I2C_GPIO(x) GPIOB_PIN(x) +#define I2C_GPIO_DIR GPIOB_DIR +#define I2C_SCL_PIN 6 +#define I2C_SDA_PIN 7 + #elif defined(SANSA_M200V4) #define I2C_GPIO(x) GPIOD_PIN(x) #define I2C_GPIO_DIR GPIOD_DIR diff --git a/firmware/target/arm/as3525/sansa-clipv2/backlight-clip.c b/firmware/target/arm/as3525/sansa-clipv2/backlight-clip.c new file mode 100644 index 0000000..5c0e16b --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/backlight-clip.c @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 Rafaël Carré + * + * 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 "backlight-target.h" +#include "lcd.h" +#include "as3525.h" +#include "ascodec-target.h" + +void _backlight_on(void) +{ + ascodec_write(0x25, ascodec_read(0x25) | 2); /* lcd power */ + ascodec_write(0x1c, 8|1); + ascodec_write(0x1b, 0x90); + lcd_enable(true); +} + +void _backlight_off(void) +{ + ascodec_write(0x25, ascodec_read(0x25) & ~2); /* lcd power */ + lcd_enable(false); +} + +void _buttonlight_on(void) +{ + GPIOA_DIR |= (1<<5); + GPIOA_PIN(5) = (1<<5); /* set pin a5 high */ +} + +void _buttonlight_off(void) +{ + GPIOA_DIR |= (1<<5); + GPIOA_PIN(5) = 0; /* set pin a5 low */ +} diff --git a/firmware/target/arm/as3525/sansa-clipv2/backlight-target.h b/firmware/target/arm/as3525/sansa-clipv2/backlight-target.h new file mode 100644 index 0000000..d202408 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/backlight-target.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 Rafaël Carré + * + * 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 + +#define _backlight_init() true + +void _backlight_on(void); +void _backlight_off(void); + +void _buttonlight_on(void); +void _buttonlight_off(void); + +#endif diff --git a/firmware/target/arm/as3525/sansa-clipv2/button-clip.c b/firmware/target/arm/as3525/sansa-clipv2/button-clip.c new file mode 100644 index 0000000..eb1d920 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/button-clip.c @@ -0,0 +1,92 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 François Dinel + * Copyright © 2008-2009 Rafaël Carré + * + * 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 "button-target.h" +#include "as3525.h" + +void button_init_device(void) +{ + GPIOA_DIR &= ~((1<<7) | (1<<3)); + GPIOD_DIR &= ~((1<<2) | (1<<1) | (1<<0)); + GPIOD_PIN(4) = 0x00; + GPIOD_PIN(5) = 0x00; + GPIOD_PIN(6) = 0x00; + GPIOD_DIR |= ((1<<6) | (1<<5) | (1<<4)); +} + +int button_read_device(void) +{ + int result = 0; + + if(button_hold()) + return result; + + /* direct GPIO connections */ + + if (GPIOA_PIN(7)) + result |= BUTTON_POWER; + + /* This is a keypad using C4-C6 as columns and B0-B2 as rows */ + GPIOD_PIN(4) = (1<<4); + + /* C4B0 is unused */ + + if (GPIOD_PIN(1)) + result |= BUTTON_VOL_UP; + + if (GPIOD_PIN(2)) + result |= BUTTON_UP; + + GPIOD_PIN(4) = 0x00; + + GPIOD_PIN(5) = (1<<5); + + if (GPIOD_PIN(0)) + result |= BUTTON_LEFT; + + if (GPIOD_PIN(1)) + result |= BUTTON_SELECT; + + if (GPIOD_PIN(2)) + result |= BUTTON_RIGHT; + + GPIOD_PIN(5) = 0x00; + + GPIOD_PIN(6) = (1<<6); + + if (GPIOD_PIN(0)) + result |= BUTTON_DOWN; + + if (GPIOD_PIN(1)) + result |= BUTTON_VOL_DOWN; + + if (GPIOD_PIN(2)) + result |= BUTTON_HOME; + + GPIOD_PIN(6) = 0x00; + + return result; +} + +bool button_hold(void) +{ + return (GPIOA_PIN(3) != 0); +} diff --git a/firmware/target/arm/as3525/sansa-clipv2/button-target.h b/firmware/target/arm/as3525/sansa-clipv2/button-target.h new file mode 100644 index 0000000..238fd1d --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/button-target.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 François Dinel + * + * 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_ + +#include +#include "config.h" + +#define HAS_BUTTON_HOLD + +void button_init_device(void); +int button_read_device(void); +bool button_hold(void); + +/* Main unit's buttons */ +#define BUTTON_HOME 0x00000001 + +#define BUTTON_VOL_UP 0x00000002 +#define BUTTON_VOL_DOWN 0x00000004 + +#define BUTTON_UP 0x00000008 +#define BUTTON_DOWN 0x00000010 +#define BUTTON_LEFT 0x00000020 +#define BUTTON_RIGHT 0x00000040 + +#define BUTTON_SELECT 0x00000080 + +#define BUTTON_POWER 0x00000100 + +#define BUTTON_MAIN (BUTTON_HOME|BUTTON_VOL_UP|BUTTON_VOL_DOWN\ + |BUTTON_UP|BUTTON_DOWN|BUTTON_LEFT|BUTTON_RIGHT\ + |BUTTON_SELECT|BUTTON_POWER) + +#define BUTTON_REMOTE 0 + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/as3525/sansa-clipv2/lcd-as-clip.S b/firmware/target/arm/as3525/sansa-clipv2/lcd-as-clip.S new file mode 100644 index 0000000..0f68a2f --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/lcd-as-clip.S @@ -0,0 +1,101 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 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 "as3525.h" + + .text + .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: + * r0 - pixel value data address + * r1 - pixel phase data address + * r2 - pixel block count + * + * Register usage: + * r3/r4 - current block of phases + * r5/r6 - current block of values + * r7 - lcd data accumulator + * r8 - phase signs mask + * lr - lcd bridge address + */ + +lcd_grey_data: + stmfd sp!, {r4-r8, lr} + mov r8, #0x80 + orr r8, r8, r8, lsl #8 + orr r8, r8, r8, lsl #16 + + ldr lr, =GPIOA_BASE + mov r3, #(1<<5) + str r3, [lr, #(4*(1<<5))] @ set pin D/C# of LCD controller (data) + + ldr lr, =DBOP_BASE + +.greyloop: + ldmia r1, {r3-r4} /* Fetch 8 pixel phases */ + ldmia r0!, {r5-r6} /* Fetch 8 pixel values */ + + mov r7, #0 + + /* set bits 15..12 */ + tst r3, #0x80 + orrne r7, r7, #0x8000 + tst r3, #0x8000 + orrne r7, r7, #0x4000 + tst r3, #0x800000 + orrne r7, r7, #0x2000 + tst r3, #0x80000000 + orrne r7, r7, #0x1000 + bic r3, r3, r8 + add r3, r3, r5 + + /* set bits 3..0 */ + tst r4, #0x80 + orrne r7, r7, #0x08 + tst r4, #0x8000 + orrne r7, r7, #0x04 + tst r4, #0x800000 + orrne r7, r7, #0x02 + tst r4, #0x80000000 + orrne r7, r7, #0x01 + bic r4, r4, r8 + add r4, r4, r6 + + stmia r1!, {r3-r4} + + strh r7, [lr, #0x10] @ DBOP_DOUT + +1: + ldr r5, [lr, #0xC] @ DBOP_STAT + ands r5, r5, #(1<<10) @ wait until push fifo empties + beq 1b + + subs r2, r2, #1 + bne .greyloop + + ldmfd sp!, {r4-r8, pc} + .size lcd_grey_data,.-lcd_grey_data diff --git a/firmware/target/arm/as3525/sansa-clipv2/lcd-ssd1303.c b/firmware/target/arm/as3525/sansa-clipv2/lcd-ssd1303.c new file mode 100644 index 0000000..5c9db82 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/lcd-ssd1303.c @@ -0,0 +1,347 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Alan Korr + * Copyright (C) 2008 François Dinel + * Copyright © 2008-2009 Rafaël Carré + * + * 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" +#include "cpu.h" +#include "string.h" + +/*** AS3525 specifics ***/ +#include "as3525.h" + +/*** definitions ***/ + +#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00) +#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10) +#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_SEGMENT_REMAP_INV ((char)0xA1) +#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_DC_DC ((char)0xAD) +#define LCD_SET_DC_DC_PART2 ((char)0x8A) +#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_COM_OUTPUT_SCAN_DIRECTION_INV ((char)0xC8) +#define LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ ((char)0xD5) +#define LCD_SET_VCOM_DESELECT_LEVEL ((char)0xDB) +#define LCD_SET_PRECHARGE_PERIOD ((char)0xD9) +#define LCD_NOP ((char)0xE3) + +/* LCD command codes */ +#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 */ + +/* DBOP initialisation, do what OF does */ +static void ams3525_dbop_init(void) +{ + CCU_IO |= (1<<12); /* ?? */ + + CGU_DBOP |= /*(1<<3)*/ 0x18 | CLK_DIV(AS3525_PCLK_FREQ, AS3525_DBOP_FREQ); + + DBOP_CTRL = 0x51004; + DBOP_TIMPOL_01 = 0x36A12F; + DBOP_TIMPOL_23 = 0xE037E037; +} + +void lcd_write_command(int byte) +{ + volatile int i = 0; + while(i<10) i++; + + /* unset D/C# (data or command) */ + GPIOB_PIN(2) = 0; + + DBOP_TIMPOL_23 = 0xE0370036; + + /* Write command */ + /* Only bits 15:12 and 3:0 of DBOP_DOUT are meaningful */ + DBOP_DOUT = (byte << 8) | byte; + + /* While push fifo is not empty */ + while ((DBOP_STAT & (1<<10)) == 0) + ; + + DBOP_TIMPOL_23 = 0xE037E037; +} + +void lcd_write_data(const fb_data* p_bytes, int count) +{ + volatile int i = 0; + while(i<10) i++; + /* set D/C# (data or command) */ + GPIOB_PIN(2) = (1<<2); + + while (count--) + { + /* Write pixels */ + /* Only bits 15:12 and 3:0 of DBOP_DOUT are meaningful */ + DBOP_DOUT = (*p_bytes << 8) | *p_bytes; + + p_bytes++; /* next packed pixels */ + + /* While push fifo is not empty */ + while ((DBOP_STAT & (1<<10)) == 0) + ; + } +} + + +/** globals **/ + +static int xoffset; /* needed for flip */ +static bool display_on = false; /* used by lcd_enable */ + +/*** hardware configuration ***/ + +int lcd_default_contrast(void) +{ + return DEFAULT_CONTRAST_SETTING; +} + +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) +{ + if (yesno) + { + lcd_write_command(LCD_SET_SEGMENT_REMAP); + lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION); + } + else + { + lcd_write_command(LCD_SET_SEGMENT_REMAP_INV); + lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION_INV); + } +} + +void lcd_enable(bool enable) +{ + if(display_on == enable) + return; + + if( (display_on = enable) ) /* simple '=' is not a typo ! */ + lcd_write_command(LCD_SET_DISPLAY_ON); + else + lcd_write_command(LCD_SET_DISPLAY_OFF); +} + +bool lcd_enabled(void) +{ + return display_on; +} + + +/* LCD init, largely based on what OF does */ +void lcd_init_device(void) +{ + int i; +#define LCD_FULLSCREEN (128+4) + fb_data p_bytes[LCD_FULLSCREEN]; /* framebuffer used to clear the screen */ + + ams3525_dbop_init(); + + GPIOB_DIR |= (1<<2)|(1<<5); + GPIOB_PIN(5) = (1<<5); + + /* Set display clock (divide ratio = 1) and oscillator frequency (1) */ + lcd_write_command(LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ); + lcd_write_command(0x10); + + /* Set VCOM deselect level to 0.76V */ + lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL); + lcd_write_command(0x34); + + /* Set pre-charge period (p1period is 2 dclk and p2period is 5 dclk) */ + lcd_write_command(LCD_SET_PRECHARGE_PERIOD); + lcd_write_command(0x25); + + /* Set contrast register to 12% */ + lcd_set_contrast(lcd_default_contrast()); + + /* Disable DC-DC */ + lcd_write_command(LCD_SET_DC_DC); + lcd_write_command(LCD_SET_DC_DC_PART2/*|0*/); + + /* Set starting line as 0 */ + lcd_write_command(LCD_SET_DISPLAY_START_LINE /*|(0 & 0x3f)*/); + + /* Column 131 is remapped to SEG0 */ + lcd_write_command(LCD_SET_SEGMENT_REMAP_INV); + + /* Invert COM scan direction (N-1 to 0) */ + lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION_INV); + + /* Set normal display mode (not every pixel ON) */ + lcd_write_command(LCD_SET_ENTIRE_DISPLAY_OFF); + + /* Set normal display mode (not inverted) */ + lcd_write_command(LCD_SET_NORMAL_DISPLAY); + + /* Clear whole framebuffer, including "overscan" + * We don't need to handle that out of screen columns in lcd_clear_display() + * since we will never write into it anymore + */ + lcd_write_command (LCD_SET_HIGHER_COLUMN_ADDRESS /*| 0*/); + lcd_write_command (LCD_SET_LOWER_COLUMN_ADDRESS /*| 0*/); + + memset(p_bytes, 0, sizeof(p_bytes)); /* fills with 0 : pixel off */ + + for(i = 0; i < 8; i++) + { + lcd_write_command (LCD_SET_PAGE_ADDRESS | (i /*& 0xf*/)); + lcd_write_data(p_bytes, LCD_FULLSCREEN /* overscan */); + } + + lcd_enable(true); + + 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) +{ + if(!display_on) + return; + + /* Copy display bitmap to hardware */ + while (bheight--) + { + lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); + lcd_write_command (LCD_CNTL_HIGHCOL | (((x+2+xoffset)>>4) & 0xf)); + lcd_write_command (LCD_CNTL_LOWCOL | ((x+2+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) +{ + if(!display_on) + return; + + stride <<= 3; /* 8 pixels per block */ + /* Copy display bitmap to hardware */ + while (bheight--) + { + lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); + lcd_write_command (LCD_CNTL_HIGHCOL | (((x+2+xoffset)>>4) & 0xf)); + lcd_write_command (LCD_CNTL_LOWCOL | ((x+2+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) ICODE_ATTR; +void lcd_update(void) +{ + int y; + + if(!display_on) + return; + + /* 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+2) >> 4) & 0xf)); + lcd_write_command (LCD_CNTL_LOWCOL | ((xoffset+2) & 0xf)); + + lcd_write_data (lcd_framebuffer[y], LCD_WIDTH); + } +} + +/* Update a fraction of the display. */ +void lcd_update_rect(int, int, int, int) ICODE_ATTR; +void lcd_update_rect(int x, int y, int width, int height) +{ + int ymax; + + if(!display_on) + return; + + /* 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+2+xoffset) >> 4) & 0xf)); + lcd_write_command (LCD_CNTL_LOWCOL | ((x+2+xoffset) & 0xf)); + + lcd_write_data (&lcd_framebuffer[y][x], width); + } +} diff --git a/firmware/target/arm/as3525/sansa-clipv2/powermgmt-clip.c b/firmware/target/arm/as3525/sansa-clipv2/powermgmt-clip.c new file mode 100644 index 0000000..d908981 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/powermgmt-clip.c @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2008 Rafaël Carré + * + * 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" + +/* The battery manufacturer's website shows discharge curves down to 3.0V, + so 'dangerous' and 'shutoff' levels of 3.4V and 3.3V should be safe. + */ +const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = +{ + 3400 +}; + +const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = +{ + 3300 +}; + +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ +const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = +{ + { 3300, 3653, 3701, 3735, 3768, 3790, 3833, 3900, 3966, 4056, 4140 } +}; + +#if CONFIG_CHARGING +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ +const unsigned short percent_to_volt_charge[11] = +{ + /* TODO: simple linear uncalibrated curve */ + 3300, 3390, 3480, 3570, 3660, 3750, 3840, 3930, 4020, 4110, 4200 +}; +#endif /* CONFIG_CHARGING */ + diff --git a/firmware/target/arm/as3525/sansa-clipv2/powermgmt-target.h b/firmware/target/arm/as3525/sansa-clipv2/powermgmt-target.h new file mode 100644 index 0000000..691d134 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-clipv2/powermgmt-target.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Michael Sevakis + * Copyright (C) 2008 by Bertrik Sikken + * + * 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 + +/* Check if topped-off and monitor voltage while plugged. */ +#define BATT_FULL_VOLTAGE 4160 +#define BATT_VAUTO_RECHARGE 4100 +#define BATT_CHG_V CHG_V_4_20V +#define BATT_CHG_I CHG_I_100MA +#define CHARGER_TOTAL_TIMER (6*3600*2) /* about 1.5 * capacity / current */ +#define ADC_BATTERY ADC_BVDD + +void powermgmt_init_target(void); +void charging_algorithm_step(void); +void charging_algorithm_close(void); + +/* We want to be able to reset the averaging filter */ +#define HAVE_RESET_BATTERY_FILTER + +#define BATT_AVE_SAMPLES 32 + +#endif /* POWERMGMT_TARGET_H */ diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 26c806e..8ce4a46 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -188,7 +188,7 @@ static void sdram_init(void) /* 16 bits external bus, low power SDRAM, 16 Mbits = 2 Mbytes */ #define MEMORY_MODEL 0x21 -#elif defined(SANSA_E200V2) || defined(SANSA_FUZE) +#elif defined(SANSA_E200V2) || defined(SANSA_FUZE) || defined(SANSA_CLIPV2) /* 16 bits external bus, high performance SDRAM, 64 Mbits = 8 Mbytes */ #define MEMORY_MODEL 0x5 @@ -217,8 +217,8 @@ static void sdram_init(void) void system_init(void) { - #ifdef BOOTLOADER /* TODO: makes this work in the main build */ +#ifndef SANSA_CLIPV2 CGU_PROC = 0; /* fclk 24 MHz */ CGU_PERI &= ~0x7f; /* pclk 24 MHz */ @@ -246,6 +246,7 @@ void system_init(void) : : : "r0" ); sdram_init(); +#endif /* SANSA_CLIPV2 */ #endif /* BOOTLOADER */ #if 0 /* the GPIO clock is already enabled by the dualboot function */ diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index 35d0aec..2172be3 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S @@ -59,6 +59,7 @@ newstart: #if CONFIG_CPU==AS3525 && !defined(BOOTLOADER) +#ifndef SANSA_CLIPV2 /* relocate vectors */ mov r1, #0 @ destination ldr r2, =_vectorscopy @ source @@ -68,6 +69,7 @@ newstart: str r0, [r1], #4 cmp r1, r3 bne 1b +#endif /* SANSA_CLIPV2 */ /* Zero out IBSS */ ldr r2, =_iedata @@ -97,7 +99,7 @@ newstart: cmp r3, r2 strhi r4, [r2], #4 bhi 1b - + /* Set up some stack and munge it with 0xdeadbeef */ ldr sp, =stackend ldr r2, =stackbegin @@ -106,12 +108,12 @@ newstart: cmp sp, r2 strhi r3, [r2], #4 bhi 1b - - /* Set up stack for IRQ mode */ + + /* Set up stack for IRQ mode */ msr cpsr_c, #0xd2 ldr sp, =irq_stack - /* Set up stack for FIQ mode */ + /* Set up stack for FIQ mode */ msr cpsr_c, #0xd1 ldr sp, =fiq_stack @@ -148,7 +150,7 @@ prefetch_abort_handler: b UIE data_abort_handler: - sub r0, lr, #8 + sub r0, lr, #8 mov r1, #2 b UIE diff --git a/rbutil/mkamsboot/Makefile b/rbutil/mkamsboot/Makefile index 5a62650..a4bb0dc 100644 --- a/rbutil/mkamsboot/Makefile +++ b/rbutil/mkamsboot/Makefile @@ -8,11 +8,13 @@ LIBUCL=../../tools/ucl/src/libucl.a # adding a new target. mkamsboot.c also needs to be edited to refer to these # new images. -BOOTIMAGES = dualboot_clip.o dualboot_e200v2.o dualboot_c200v2.o dualboot_m200v4.o dualboot_fuze.o -BOOTHEADERS = dualboot_clip.h dualboot_e200v2.h dualboot_c200v2.h dualboot_m200v4.h dualboot_fuze.h +BOOTIMAGES = dualboot_clip.o dualboot_e200v2.o dualboot_c200v2.o dualboot_m200v4.o dualboot_fuze.o dualboot_clipv2.o +BOOTHEADERS = dualboot_clip.h dualboot_e200v2.h dualboot_c200v2.h dualboot_m200v4.h dualboot_fuze.h dualboot_clipv2.h CLIPFILES = dualboot_clip.arm-o dualboot_clip.o dualboot_clip.c dualboot_clip.h +CLIPV2FILES = dualboot_clipv2.arm-o dualboot_clipv2.o dualboot_clipv2.c dualboot_clipv2.h + E200V2FILES = dualboot_e200v2.arm-o dualboot_e200v2.o dualboot_e200v2.c \ dualboot_e200v2.h @@ -31,6 +33,9 @@ all: mkamsboot dualboot_clip.arm-o: dualboot.S arm-elf-gcc -DSANSA_CLIP -c -o dualboot_clip.arm-o dualboot.S +dualboot_clipv2.arm-o: dualboot.S + arm-elf-gcc -DSANSA_CLIPV2 -c -o dualboot_clipv2.arm-o dualboot.S + dualboot_fuze.arm-o: dualboot.S arm-elf-gcc -DSANSA_FUZE -c -o dualboot_fuze.arm-o dualboot.S @@ -87,4 +92,4 @@ clean: rm -f mkamsboot mkamsboot.o nrv2e_d8.arm-o nrv2e_d8.arm-elf \ nrv2e_d8.arm-bin *~ bin2c nrv2e_d8.c nrv2e_d8.h nrv2e_d8.o md5.o \ $(BOOTIMAGES) $(CLIPFILES) $(E200V2FILES) $(M200V4FILES) $(FUZEFILES) \ - $(C200V2FILES) + $(C200V2FILES) $(CLIPV2FILES) diff --git a/rbutil/mkamsboot/dualboot.S b/rbutil/mkamsboot/dualboot.S index 3b744f8..514fb1d 100644 --- a/rbutil/mkamsboot/dualboot.S +++ b/rbutil/mkamsboot/dualboot.S @@ -21,10 +21,11 @@ .text -/* This is the size of the Clip's RAM, but there is nothing to be gained - (at the moment) by making use of the larger RAM of other targets */ - -.set DRAM_SIZE, 0x50000 +#if defined(SANSA_CLIPV2) +.set RAM_SIZE, 0x100000 /* Use 1MB of SDRAM on V2 models (bigger firmwares) */ +#else +.set RAM_SIZE, 0x50000 /* Use full IRAM on V1 models */ +#endif .set GPIOA, 0xC80B0000 .set GPIOB, 0xC80C0000 @@ -60,7 +61,7 @@ start: ldr r1, uclunpack_size /* Source length */ sub r2, r0, r1 /* Source start - 1*/ - ldr r3, =(DRAM_SIZE-1) /* Destination end */ + ldr r3, =(RAM_SIZE-1) /* Destination end */ uclcopy: ldrb r4, [r0], #-1 @@ -88,7 +89,7 @@ uclcopy: str r1, [r0, #0x400] #ifdef SANSA_C200V2 ldr r1, [r0, #0x8] /* USB is A1 on C200 */ -#elif defined(SANSA_CLIP) +#elif defined(SANSA_CLIP) || defined(SANSA_CLIPV2) ldr r1, [r0, #0x100] /* USB is A6 on Clip */ #else ldr r1, [r0, #0x20] /* read pin A3 */ @@ -115,6 +116,26 @@ uclcopy: cmp r1, #0 bne boot_of +#elif defined(SANSA_CLIPV2) + /* HOME button */ +.set row, (1<<6) /* enable output on D6 */ + ldr r0, =GPIOD + mov r1, #((1<<6)|(1<<5)|(1<<4)) + str r1, [r0, #0x400] + + mov r1, #0 @ zero all rows first + str r1, [r0, #(4*(1<<4))] + str r1, [r0, #(4*(1<<5))] + str r1, [r0, #(4*(1<<6))] + + mov r1, #row + str r1, [r0, #(4*row)] + +.set col, (1<<2) /* read keyscan column D2 */ + ldr r1, [r0, #(4*col)] + + cmp r1, #0 + beq boot_of #elif defined(SANSA_E200V2) || defined(SANSA_FUZE) /* LEFT button */ ldr r0, =GPIOC diff --git a/rbutil/mkamsboot/extract_fw.c b/rbutil/mkamsboot/extract_fw.c index e91d1f8..8ada918 100644 --- a/rbutil/mkamsboot/extract_fw.c +++ b/rbutil/mkamsboot/extract_fw.c @@ -105,7 +105,11 @@ int main(int argc, char* argv[]) close(fdin); /* Get the firmware size */ - firmware_size = get_uint32le(&buf[0x0c]); + if (get_uint32le(&buf[0x04])==0x0000f000) + firmware_size = get_uint32le(&buf[0x10]); /*v2*/ + else + firmware_size = get_uint32le(&buf[0x0c]); + fdout = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666); diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c index a7f6ad6..44b59b0 100644 --- a/rbutil/mkamsboot/mkamsboot.c +++ b/rbutil/mkamsboot/mkamsboot.c @@ -50,9 +50,10 @@ as follows: This entire block fits into the space previously occupied by the main firmware block - the space saved by compressing the OF image is used -to store the compressed version of the Rockbox bootloader. The OF -image is typically about 120KB, which allows us to store a Rockbox -bootloader with an uncompressed size of about 60KB-70KB. +to store the compressed version of the Rockbox bootloader. On version 1 +firmwares, The OF image is typically about 120KB, which allows us to +store a Rockbox bootloader with an uncompressed size of about 60KB-70KB. +Version 2 firmwares are bigger and are stored in SDRAM (instead of IRAM). mkamsboot then corrects the checksums and writes a new legal firmware file which can be installed on the device. @@ -90,6 +91,7 @@ execution to the uncompressed firmware. #include "md5.h" #include "dualboot_clip.h" +#include "dualboot_clipv2.h" #include "dualboot_e200v2.h" #include "dualboot_fuze.h" #include "dualboot_m200v4.h" @@ -129,7 +131,7 @@ static const unsigned char* bootloaders[] = { dualboot_fuze, dualboot_clip, - NULL, + dualboot_clipv2, dualboot_e200v2, dualboot_m200v4, dualboot_c200v2, @@ -139,7 +141,7 @@ static const int bootloader_sizes[] = { sizeof(dualboot_fuze), sizeof(dualboot_clip), - 0, + sizeof(dualboot_clipv2), sizeof(dualboot_e200v2), sizeof(dualboot_m200v4), sizeof(dualboot_c200v2), @@ -151,7 +153,7 @@ static const char* rb_model_names[] = { "fuze", "clip", - NULL, + "clv2", "e2v2", "m2v4", "c2v2", @@ -163,7 +165,7 @@ static const int rb_model_num[] = { 43, 40, - 0, + 46, 41, 42, 44 @@ -200,6 +202,9 @@ static struct md5sums sansasums[] = { { MODEL_CLIP, "1.01.20", 1, "236d8f75189f468462c03f6d292cf2ac" }, { MODEL_CLIP, "1.01.29", 1, "c12711342169c66e209540cd1f27cd26" }, { MODEL_CLIP, "1.01.30", 1, "f2974d47c536549c9d8259170f1dbe4d" }, + + { MODEL_CLIPV2, "2.01.16", 2, "c57fb3fcbe07c2c9b360f060938f80cb" }, + { MODEL_CLIPV2, "2.01.32", 2, "0ad3723e52022509089d938d0fbbf8c5" } }; #define NUM_MD5S (sizeof(sansasums)/sizeof(sansasums[0])) @@ -514,7 +519,10 @@ int main(int argc, char* argv[]) printf("[INFO] Patching %s firmware\n",model_names[model]); /* Get the firmware size */ - firmware_size = get_uint32le(&buf[0x0c]); + if (fw_version == 1) + firmware_size = get_uint32le(&buf[0x0c]); + else + firmware_size = get_uint32le(&buf[0x10]); /* Compress the original firmware image */ of_packed = uclpack(buf + 0x400, firmware_size, &of_packedsize); @@ -552,7 +560,6 @@ int main(int argc, char* argv[]) if (totalsize > firmware_size) { fprintf(stderr,"[ERR] No room to insert bootloader, aborting\n"); free(buf); - free(rb_unpacked); free(of_packed); return 1; } @@ -603,8 +610,6 @@ int main(int argc, char* argv[]) put_uint32le(&buf[0x04], sum); put_uint32le(&buf[0x204], sum); } else { - /* TODO: Verify that this is correct for the v2 firmware */ - put_uint32le(&buf[0x08], sum); put_uint32le(&buf[0x208], sum); diff --git a/tools/configure b/tools/configure index cc5c76e..e2d7a5b 100755 --- a/tools/configure +++ b/tools/configure @@ -736,20 +736,20 @@ cat <