diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c index 6da546fcac..4537c4b43f 100644 --- a/bootloader/sansa_as3525.c +++ b/bootloader/sansa_as3525.c @@ -46,6 +46,10 @@ void main(void) system_init(); kernel_init(); +#ifdef SANSA_C200V2 + /* stop here */ + while(1); +#endif lcd_init(); show_logo(); diff --git a/firmware/SOURCES b/firmware/SOURCES index fd0ec39f2f..c1771a3935 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1100,6 +1100,19 @@ target/arm/as3525/powermgmt-as3525.c #endif /* !SIMULATOR */ #endif /* SANSA_E200V2 */ +#ifdef SANSA_C200V2 +#ifndef SIMULATOR +target/arm/as3525/sansa-c200v2/lcd-c200v2.c +target/arm/as3525/sansa-c200v2/button-c200v2.c +target/arm/as3525/sansa-c200v2/backlight-c200v2.c +#ifndef BOOTLOADER +drivers/generic_i2c.c +target/arm/as3525/fmradio-i2c-as3525.c +target/arm/as3525/powermgmt-as3525.c +#endif /* !BOOTLOADER */ +#endif /* !SIMULATOR */ +#endif /* SANSA_E200V2 */ + #ifdef SANSA_M200V4 #ifndef SIMULATOR target/arm/lcd-ssd1815.c diff --git a/firmware/export/config-c200v2.h b/firmware/export/config-c200v2.h new file mode 100644 index 0000000000..6ecb478c09 --- /dev/null +++ b/firmware/export/config-c200v2.h @@ -0,0 +1,209 @@ +/* + * This config file is for the Sandisk Sansa e200 + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 44 +#define MODEL_NAME "Sandisk Sansa c200v2 series" + +#define HW_SAMPR_CAPS (SAMPR_CAP_44) + +#if 0 +/* 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 + +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_FMRADIO) +#endif + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR + +/* define this if you want album art for this target */ +#define HAVE_ALBUMART + +/* 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 132 +#define LCD_HEIGHT 80 +#define LCD_DEPTH 16 /* 65536 colours */ +#define LCD_PIXELFORMAT RGB565 /* rgb565 */ + +#ifndef BOOTLOADER +/* define this if you have LCD enable function */ +#define HAVE_LCD_ENABLE + +/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE + should be defined as well. */ +/* TODO: #define HAVE_LCD_SLEEP */ +/* TODO: #define HAVE_LCD_SLEEP_SETTING <= optional */ +#endif +/* define this if you can flip your LCD */ +#define HAVE_LCD_FLIP + +/* define this if you can invert the colours on your LCD */ +/* TODO: #define HAVE_LCD_INVERT */ + +#if 0 +/* Define this if your LCD can set contrast */ +#define HAVE_LCD_CONTRAST + +#define MIN_CONTRAST_SETTING 0 +#define MAX_CONTRAST_SETTING 255 +#define DEFAULT_CONTRAST_SETTING 85 +#endif +/* #define IRAM_LCDFRAMEBUFFER IDATA_ATTR *//* put the lcd frame buffer in IRAM */ + +#define CONFIG_KEYPAD SANSA_C200_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 + +/* The PP5024 has a built-in AustriaMicrosystems AS3514 */ +#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 + +/* Some Sansa E200s seem to be FAT16 formatted */ +#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 - suspected to be the SI4702 */ +//#define CONFIG_TUNER SI4700 +/* #define HAVE_TUNER_PWR_CTRL */ + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT +#define HAVE_BACKLIGHT_BRIGHTNESS + +/* 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 530 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 530 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 530 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 0 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* Hardware controlled charging? FIXME */ +#define CONFIG_CHARGING CHARGING_SIMPLE + +/* define this if the unit can be powered or charged via USB */ +#define HAVE_USB_POWER + +/** Non-simulator section **/ +#ifndef SIMULATOR + +/* define this if the backlight thread is used for fade, not for sim, needs + * HAVE_BACKLIGHT_BRIGHTNESS */ +#ifndef BOOTLOADER +#define USE_BACKLIGHT_SW_FADING +#endif + +/* Define this if you have a PortalPlayer PP5024 */ +#define CONFIG_CPU AS3525 + +/* Define this if you want to use the PP5024 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 75000000 + +/* Type of LCD TODO: hopefully the same as the x5 but check this*/ +#define CONFIG_LCD LCD_C200 + +/* Offset ( in the firmware file's header ) to the file CRC and data. These are + only used when loading the old format rockbox.e200 file */ +#define FIRMWARE_OFFSET_FILE_CRC 0x0 +#define FIRMWARE_OFFSET_FILE_DATA 0x8 + +/* #define USB_IPODSTYLE */ + +#ifndef BOOTLOADER +#define HAVE_MULTIVOLUME +#define HAVE_HOTSWAP +#endif + +/* 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 0x7450 +/* 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 d484805532..d8c14ddcef 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -330,6 +330,8 @@ #include "config-m200v4.h" #elif defined(SANSA_FUZE) #include "config-fuze.h" +#elif defined(SANSA_C200V2) +#include "config-c200v2.h" #else /* no known platform */ #endif diff --git a/firmware/target/arm/as3525/clock-target.h b/firmware/target/arm/as3525/clock-target.h index fd8cb021fa..1e55753555 100644 --- a/firmware/target/arm/as3525/clock-target.h +++ b/firmware/target/arm/as3525/clock-target.h @@ -56,6 +56,8 @@ #define AS3525_DBOP_FREQ 24000000 #elif defined(SANSA_E200V2) #define AS3525_DBOP_FREQ 8000000 +#elif defined(SANSA_C200V2) +#define AS3525_DBOP_FREQ 8000000 #endif /* macro for not giving a target clock > at the one provided */ diff --git a/firmware/target/arm/as3525/sansa-c200v2/backlight-c200v2.c b/firmware/target/arm/as3525/sansa-c200v2/backlight-c200v2.c new file mode 100644 index 0000000000..ba9db6a1f5 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-c200v2/backlight-c200v2.c @@ -0,0 +1,71 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: backlight-e200v2-fuze.c 19224 2008-11-26 10:21:03Z pondlife $ + * + * Copyright (C) 2006 by Barry Wardell + * + * 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 "backlight-target.h" +#include "system.h" +#include "lcd.h" +#include "backlight.h" +#include "ascodec-target.h" +#include "as3514.h" + +/* TODO: This file is copy & pasted from backlight-e200v2-fuze.c, as I think + * it'll be the same for c200v2; prove it */ +void _backlight_set_brightness(int brightness) +{ + if (brightness > 0) + _backlight_on(); + else + _backlight_off(); +} + +void _backlight_on(void) +{ +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(false); /* stop counter */ +#endif +#ifdef HAVE_LCD_ENABLE + lcd_enable(true); /* power on lcd + visible display */ +#endif + ascodec_write(AS3514_DCDC15, backlight_brightness); +} + +void _backlight_off(void) +{ + ascodec_write(AS3514_DCDC15, 0x0); +#ifdef HAVE_LCD_ENABLE + lcd_enable(false); /* power off visible display */ +#endif +#ifdef HAVE_LCD_SLEEP + backlight_lcd_sleep_countdown(true); /* start countdown */ +#endif +} + +void _buttonlight_on(void) +{ + GPIOD_DIR |= (1<<7); + GPIOD_PIN(7) = (1<<7); +} + +void _buttonlight_off(void) +{ + GPIOD_DIR |= (1<<7); + GPIOD_PIN(7) = 0; +} diff --git a/firmware/target/arm/as3525/sansa-c200v2/backlight-target.h b/firmware/target/arm/as3525/sansa-c200v2/backlight-target.h new file mode 100644 index 0000000000..e8a60fa881 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-c200v2/backlight-target.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: backlight-target.h 19136 2008-11-18 13:44:27Z dave $ + * + * Copyright (C) 2006 Barry Wardell + * + * 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 _backlight_set_brightness(int brightness); +int __backlight_is_on(void); + +void _buttonlight_on(void); +void _buttonlight_off(void); +#endif diff --git a/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c new file mode 100644 index 0000000000..18ae41ce97 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-c200v2/button-c200v2.c @@ -0,0 +1,111 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: button-e200v2.c 19035 2008-11-07 05:31:05Z jdgordon $ + * + * Copyright (C) 2006 by Barry Wardell + * + * 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. + * + ****************************************************************************/ + +/* Taken from button-h10.c by Barry Wardell and reverse engineering by MrH. */ + +#include "system.h" +#include "button.h" +#include "backlight.h" +#include "powermgmt.h" + + +#ifndef BOOTLOADER +/* Buttons */ +static bool hold_button = false; +static bool hold_button_old = false; +#define _button_hold() hold_button +#else +#define _button_hold() false /* FIXME */ +#endif /* BOOTLOADER */ +static int int_btn = BUTTON_NONE; + +void button_init_device(void) +{ +} + +bool button_hold(void) +{ + return _button_hold(); +} + +/* device buttons */ +void button_int(void) +{ + int delay = 0x50; + int dir_save_c = 0; + int afsel_save_c = 0; + + int_btn = BUTTON_NONE; + + /* Save the current direction and afsel */ + dir_save_c = GPIOC_DIR; + afsel_save_c = GPIOC_AFSEL; + + GPIOA_DIR &= ~(1<<2); + GPIOC_AFSEL &= ~(1<<6|1<<5|1<<4|1<<3); + GPIOC_DIR |= (1<<6|1<<5|1<<4|1<<3); + + /* These should not be needed with button event interupts */ + /* they are necessary now to clear out lcd data */ + + GPIOC_PIN(6) = (1<<6); + GPIOC_PIN(5) = (1<<5); + GPIOC_PIN(4) = (1<<4); + GPIOC_PIN(3) = (1<<3); + GPIOC_DIR &= ~(1<<6|1<<5|1<<4|1<<3); + + while(delay--); + + /* direct GPIO connections */ + if (GPIOA_PIN(3)) + int_btn |= BUTTON_POWER; + if (!GPIOC_PIN(6)) + int_btn |= BUTTON_RIGHT; + if (!GPIOC_PIN(5)) + int_btn |= BUTTON_UP; + if (!GPIOC_PIN(4)) + int_btn |= BUTTON_SELECT; + if (!GPIOC_PIN(3)) + int_btn |= BUTTON_DOWN; + + /* return to settings needed for lcd */ + GPIOC_DIR = dir_save_c; + GPIOC_AFSEL = afsel_save_c; +} + +/* + * Get button pressed from hardware + */ +int button_read_device(void) +{ + /* Read buttons directly */ + button_int(); +#ifndef BOOTLOADER + /* light handling */ + if (hold_button != hold_button_old) + { + hold_button_old = hold_button; + backlight_hold_changed(hold_button); + } +#endif /* BOOTLOADER */ + + return int_btn; +} diff --git a/firmware/target/arm/as3525/sansa-c200v2/button-target.h b/firmware/target/arm/as3525/sansa-c200v2/button-target.h new file mode 100644 index 0000000000..cc668c4015 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-c200v2/button-target.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id:$ + * + * Copyright (C) 2007 by Mark Arigo + * + * 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 + +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); + +/* Sandisk Sansa c200 button codes */ + +/* Main unit's buttons */ +#define BUTTON_REC 0x00000001 +#define BUTTON_DOWN 0x00000002 +#define BUTTON_RIGHT 0x00000004 +#define BUTTON_LEFT 0x00000008 +#define BUTTON_SELECT 0x00000010 +#define BUTTON_UP 0x00000020 +#define BUTTON_POWER 0x00000040 +#define BUTTON_VOL_UP 0x00000080 +#define BUTTON_VOL_DOWN 0x00000100 + +#define BUTTON_MAIN 0x00000fff + +/* No Remote control */ +#define BUTTON_REMOTE 0 + +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/as3525/sansa-c200v2/lcd-c200v2.c b/firmware/target/arm/as3525/sansa-c200v2/lcd-c200v2.c new file mode 100644 index 0000000000..2fc3e1f6c5 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-c200v2/lcd-c200v2.c @@ -0,0 +1,429 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: lcd-e200v2.c 19453 2008-12-16 02:50:39Z saratoga $ + * + * 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. + * + ****************************************************************************/ + +/* FIXME: Copied from e200v2 lcd driver, unlikely to work, but maybe */ + +#include "config.h" + +#include "cpu.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include +#include +#include "file.h" +#include "debug.h" +#include "system.h" +#include "font.h" +#include "bidi.h" +#include "clock-target.h" + +static bool display_on = false; /* is the display turned on? */ +static bool display_flipped = false; +static int y_offset = 0; /* needed for flip */ + +/* register defines */ +#define R_START_OSC 0x00 +#define R_DRV_OUTPUT_CONTROL 0x01 +#define R_DRV_WAVEFORM_CONTROL 0x02 +#define R_ENTRY_MODE 0x03 +#define R_COMPARE_REG1 0x04 +#define R_COMPARE_REG2 0x05 + +#define R_DISP_CONTROL1 0x07 +#define R_DISP_CONTROL2 0x08 +#define R_DISP_CONTROL3 0x09 + +#define R_FRAME_CYCLE_CONTROL 0x0b +#define R_EXT_DISP_IF_CONTROL 0x0c + +#define R_POWER_CONTROL1 0x10 +#define R_POWER_CONTROL2 0x11 +#define R_POWER_CONTROL3 0x12 +#define R_POWER_CONTROL4 0x13 + +#define R_RAM_ADDR_SET 0x21 +#define R_WRITE_DATA_2_GRAM 0x22 + +#define R_GAMMA_FINE_ADJ_POS1 0x30 +#define R_GAMMA_FINE_ADJ_POS2 0x31 +#define R_GAMMA_FINE_ADJ_POS3 0x32 +#define R_GAMMA_GRAD_ADJ_POS 0x33 + +#define R_GAMMA_FINE_ADJ_NEG1 0x34 +#define R_GAMMA_FINE_ADJ_NEG2 0x35 +#define R_GAMMA_FINE_ADJ_NEG3 0x36 +#define R_GAMMA_GRAD_ADJ_NEG 0x37 + +#define R_GAMMA_AMP_ADJ_RES_POS 0x38 +#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 + +#define R_GATE_SCAN_POS 0x40 +#define R_VERT_SCROLL_CONTROL 0x41 +#define R_1ST_SCR_DRV_POS 0x42 +#define R_2ND_SCR_DRV_POS 0x43 +#define R_HORIZ_RAM_ADDR_POS 0x44 +#define R_VERT_RAM_ADDR_POS 0x45 + +#define R_ENTRY_MODE_HORZ 0x7030 +#define R_ENTRY_MODE_VERT 0x7038 +#define R_ENTRY_MODE_SOLID_VERT 0x1038 + +/* TODO: Implement this function */ +static void lcd_delay(int x) +{ + /* This is just arbitrary - the OF does something more complex */ + x *= 1024; + while (x--); +} + +/* DBOP initialisation, do what OF does */ +static void ams3525_dbop_init(void) +{ + CGU_DBOP = (1<<3) | CLK_DIV(AS3525_PCLK_FREQ, AS3525_DBOP_FREQ); + + DBOP_TIMPOL_01 = 0xe167e167; + DBOP_TIMPOL_23 = 0xe167006e; + DBOP_CTRL = 0x41008; + + GPIOB_AFSEL = 0xfc; + GPIOC_AFSEL = 0xff; + + DBOP_TIMPOL_23 = 0x6000e; + DBOP_CTRL = 0x51008; + DBOP_TIMPOL_01 = 0x6e167; + DBOP_TIMPOL_23 = 0xa167e06f; + + /* TODO: The OF calls some other functions here, but maybe not important */ +} + + +static void lcd_write_cmd(int cmd) +{ + /* Write register */ + DBOP_CTRL &= ~(1<<14); + + DBOP_TIMPOL_23 = 0xa167006e; + + DBOP_DOUT = cmd; + + /* Wait for fifo to empty */ + while ((DBOP_STAT & (1<<10)) == 0); + + DBOP_TIMPOL_23 = 0xa167e06f; +} + +void lcd_write_data(const fb_data* p_bytes, int count) +{ + while (count--) + { + DBOP_DOUT = *p_bytes++; + + /* Wait for fifo to empty */ + while ((DBOP_STAT & (1<<10)) == 0); + } +} + +static void lcd_write_reg(int reg, int value) +{ + unsigned short data = value; + + lcd_write_cmd(reg); + lcd_write_data(&data, 1); +} + +/*** hardware configuration ***/ + +void lcd_set_contrast(int val) +{ + (void)val; +} + +void lcd_set_invert_display(bool yesno) +{ + (void)yesno; +} + +static void flip_lcd(bool yesno) +{ + (void)yesno; +} + + +/* turn the display upside down (call lcd_update() afterwards) */ +void lcd_set_flip(bool yesno) +{ + display_flipped = yesno; + y_offset = yesno ? 4 : 0; /* FIXME: Is a y_offset needed? */ + + if (display_on) + flip_lcd(yesno); +} + +static void _display_on(void) +{ + /* Initialisation the display the same way as the original firmware */ + + lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscilation */ + + lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x011b); /* 220 lines, GS=0, SS=1 */ + + /* B/C = 1: n-line inversion form + * EOR = 1: polarity inversion occurs by applying an EOR to odd/even + * frame select signal and an n-line inversion signal. + * FLD = 01b: 1 field interlaced scan, external display iface */ + lcd_write_reg(R_DRV_WAVEFORM_CONTROL, 0x0700); + + /* Address counter updated in horizontal direction; left to right; + * vertical increment horizontal increment. + * data format for 8bit transfer or spi = 65k (5,6,5) */ + lcd_write_reg(R_ENTRY_MODE, 0x0030); + + /* Replace data on writing to GRAM */ + lcd_write_reg(R_COMPARE_REG1, 0); + lcd_write_reg(R_COMPARE_REG2, 0); + + lcd_write_reg(R_DISP_CONTROL1, 0x0000); /* GON = 0, DTE = 0, D1-0 = 00b */ + + /* Front porch lines: 2; Back porch lines: 2; */ + lcd_write_reg(R_DISP_CONTROL2, 0x0203); + + /* Scan cycle = 0 frames */ + lcd_write_reg(R_DISP_CONTROL3, 0x0000); + + /* 16 clocks */ + lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0000); + + /* 18-bit RGB interface (one transfer/pixel) + * internal clock operation; + * System interface/VSYNC interface */ + lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0x0000); + + + /* zero everything*/ + lcd_write_reg(R_POWER_CONTROL1, 0x0000); /* STB = 0, SLP = 0 */ + + lcd_delay(10); + + /* initialise power supply */ + + /* DC12-10 = 000b: Step-up1 = clock/8, + * DC02-00 = 000b: Step-up2 = clock/16, + * VC2-0 = 010b: VciOUT = 0.87 * VciLVL */ + lcd_write_reg(R_POWER_CONTROL2, 0x0002); + + /* VRH3-0 = 1000b: Vreg1OUT = REGP * 1.90 */ + lcd_write_reg(R_POWER_CONTROL3, 0x0008); + + lcd_delay(40); + + lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG = 0 */ + + /* This register is unknown */ + lcd_write_reg(0x56, 0x80f); + + + lcd_write_reg(R_POWER_CONTROL1, 0x4140); + + lcd_delay(10); + + lcd_write_reg(R_POWER_CONTROL2, 0x0000); + lcd_write_reg(R_POWER_CONTROL3, 0x0013); + + lcd_delay(20); + + lcd_write_reg(R_POWER_CONTROL4, 0x6d0e); + + lcd_delay(20); + + lcd_write_reg(R_POWER_CONTROL4, 0x6d0e); + + lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0002); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0707); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0182); + lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0203); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0706); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0006); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0706); + lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0000); + lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0x030f); + lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0x0f08); + + + lcd_write_reg(R_RAM_ADDR_SET, 0); + lcd_write_reg(R_GATE_SCAN_POS, 0); + lcd_write_reg(R_VERT_SCROLL_CONTROL, 0); + + lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); + lcd_write_reg(R_2ND_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); + + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); + lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_HEIGHT-1) << 8); + + + lcd_write_reg(R_DISP_CONTROL1, 0x0037); + + display_on=true; /* must be done before calling lcd_update() */ + lcd_update(); +} + +/* LCD init */ +void lcd_init_device(void) +{ + ams3525_dbop_init(); + + /* Init GPIOs the same as the OF */ + + GPIOA_DIR |= (1<<5); + GPIOA_PIN(5) = 0; + + GPIOA_PIN(3) = (1<<3); + + GPIOA_DIR |= (3<<3); + + GPIOA_PIN(3) = (1<<3); + + GPIOA_PIN(4) = 0; /*c80b0040 := 0;*/ + + GPIOA_DIR |= (1<<7); + GPIOA_PIN(7) = 0; + + lcd_delay(1); + + GPIOA_PIN(5) = (1<<5); + + lcd_delay(1); + + _display_on(); +} + +void lcd_enable(bool on) +{ + if(display_on!=on) + { + if(on) + { + _display_on(); + lcd_call_enable_hook(); + } + else + { + /* TODO: Implement off sequence */ + display_on=false; + } + } +} + +bool lcd_enabled(void) +{ + return display_on; +} + +void lcd_sleep(void) +{ + /* TODO */ +} + +/*** update functions ***/ + +/* Performance function to blit a YUV bitmap directly to the LCD + * src_x, src_y, width and height should be even + * x, y, width and height have to be within LCD bounds + */ +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + (void)src; + (void)src_x; + (void)src_y; + (void)stride; + (void)x; + (void)y; + (void)width; + (void)height; +} + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + if (!display_on) + return; + + lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + + /* Set start position and window */ + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH-1) << 8); + lcd_write_reg(R_VERT_RAM_ADDR_POS, + ((y_offset + LCD_HEIGHT-1) << 8) | y_offset); + lcd_write_reg(R_RAM_ADDR_SET, (y_offset) << 8); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); + +} /* lcd_update */ + + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) +{ + int ymax; + const unsigned short *ptr; + + if (!display_on) + return; + + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; /* Clip right */ + if (x < 0) + width += x, x = 0; /* Clip left */ + if (width <= 0) + return; /* nothing left to do */ + + ymax = y + height; + if (ymax > LCD_HEIGHT) + ymax = LCD_HEIGHT; /* Clip bottom */ + if (y < 0) + y = 0; /* Clip top */ + if (y >= ymax) + return; /* nothing left to do */ + + lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + /* Set start position and window */ + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, + ((x + width-1) << 8) | x); + lcd_write_reg(R_VERT_RAM_ADDR_POS, + ((y_offset + y + height - 1) << 8) | (y_offset + y)); + lcd_write_reg(R_RAM_ADDR_SET, ((y + y_offset) << 8) | x); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + ptr = (unsigned short *)&lcd_framebuffer[y][x]; + + do + { + lcd_write_data(ptr, width); + ptr += LCD_WIDTH; + } + while (++y < ymax); +} /* lcd_update_rect */ diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index c2a2e4f47d..f2f2c0b454 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -183,7 +183,7 @@ static void sdram_init(void) MPMC_DYNAMIC_tRRD = 2; MPMC_DYNAMIC_tMRD = 2; -#if defined(SANSA_CLIP) || defined(SANSA_M200V4) +#if defined(SANSA_CLIP) || defined(SANSA_M200V4) || defined(SANSA_C200V2) /* 16 bits external bus, low power SDRAM, 16 Mbits = 2 Mbytes */ #define MEMORY_MODEL 0x21 diff --git a/tools/configure b/tools/configure index 979d8cea7c..1bf72f89dc 100755 --- a/tools/configure +++ b/tools/configure @@ -706,8 +706,9 @@ cat <