Index: apps/keymaps/keymap-fuze.c =================================================================== --- apps/keymaps/keymap-fuze.c (Revision 20122) +++ apps/keymaps/keymap-fuze.c (Arbeitskopie) @@ -41,15 +41,13 @@ { ACTION_STD_NEXTREPEAT, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_STD_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, - { ACTION_STD_REC, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT }, { ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE }, - { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, { ACTION_STD_QUICKSCREEN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, - { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT }, + { ACTION_STD_CONTEXT, BUTTON_HOME|BUTTON_REL, BUTTON_HOME }, LAST_ITEM_IN_LIST }; /* button_context_standard */ @@ -78,11 +76,10 @@ { ACTION_WPS_BROWSE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT }, - { ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT }, + { ACTION_WPS_CONTEXT, BUTTON_HOME|BUTTON_REL, BUTTON_NONE }, { ACTION_WPS_QUICKSCREEN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_WPS_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, - { ACTION_WPS_REC, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_WPS_PITCHSCREEN, BUTTON_SELECT|BUTTON_UP, BUTTON_SELECT }, { ACTION_WPS_ID3SCREEN, BUTTON_SELECT|BUTTON_DOWN, BUTTON_SELECT }, @@ -91,16 +88,16 @@ }; /* button_context_wps */ static const struct button_mapping button_context_settings[] = { - { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE }, { ACTION_SETTINGS_INC, BUTTON_SCROLL_FWD, BUTTON_NONE }, { ACTION_SETTINGS_INCREPEAT,BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_SETTINGS_DEC, BUTTON_SCROLL_BACK, BUTTON_NONE }, { ACTION_SETTINGS_DECREPEAT,BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE }, - - { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, - { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, - { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_PREV, BUTTON_UP|BUTTON_REL, BUTTON_UP }, + { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP }, + { ACTION_STD_NEXT, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, + { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_SETTINGS_RESET, BUTTON_SELECT, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), @@ -108,7 +105,7 @@ static const struct button_mapping button_context_list[] = { { ACTION_LISTTREE_PGUP, BUTTON_HOME|BUTTON_SCROLL_BACK, BUTTON_HOME }, - { ACTION_LISTTREE_PGDOWN, BUTTON_HOME|BUTTON_SCROLL_FWD, BUTTON_HOME }, + { ACTION_LISTTREE_PGDOWN, BUTTON_HOME|BUTTON_SCROLL_FWD, BUTTON_HOME }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_list */ @@ -171,15 +168,14 @@ { ACTION_SETTINGS_DEC, BUTTON_SCROLL_BACK, BUTTON_NONE }, { ACTION_SETTINGS_DECREPEAT, BUTTON_SCROLL_BACK|BUTTON_REPEAT,BUTTON_NONE }, - { ACTION_STD_PREV, BUTTON_UP|BUTTON_REL, BUTTON_NONE }, - { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_STD_NEXT, BUTTON_DOWN|BUTTON_REL, BUTTON_NONE }, - { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_PREV, BUTTON_UP|BUTTON_REL, BUTTON_UP }, + { ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP }, + { ACTION_STD_NEXT, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, + { ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_NONE, BUTTON_SELECT, BUTTON_NONE }, { ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE }, - { ACTION_NONE, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, - { ACTION_NONE, BUTTON_POWER, BUTTON_NONE }, - { ACTION_STD_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT }, + { ACTION_STD_OK, BUTTON_RIGHT, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), }; /* button_context_settings_right_is_inc */ @@ -194,15 +190,15 @@ }; /* button_context_settings_time */ static const struct button_mapping button_context_pitchscreen[] = { - { ACTION_PS_INC_SMALL, BUTTON_SCROLL_FWD, BUTTON_NONE }, - { ACTION_PS_INC_BIG, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_INC_SMALL, BUTTON_SCROLL_FWD, BUTTON_NONE }, + { ACTION_PS_INC_BIG, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_PS_DEC_SMALL, BUTTON_SCROLL_BACK, BUTTON_NONE }, { ACTION_PS_DEC_BIG, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_PS_NUDGE_LEFT, BUTTON_LEFT, BUTTON_NONE }, { ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE }, - { ACTION_PS_TOGGLE_MODE, BUTTON_HOME, BUTTON_NONE }, + { ACTION_PS_TOGGLE_MODE, BUTTON_HOME, BUTTON_NONE }, { ACTION_PS_RESET, BUTTON_SELECT, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE }, { ACTION_PS_EXIT, BUTTON_UP, BUTTON_NONE }, @@ -210,12 +206,13 @@ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD), }; /* button_context_pitchscreen */ +#ifdef HAVE_RECORDING /** Recording Screen **/ static const struct button_mapping button_context_recscreen[] = { { ACTION_REC_PAUSE, BUTTON_UP|BUTTON_REL, BUTTON_UP }, - { ACTION_STD_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, - { ACTION_REC_NEWFILE, BUTTON_HOME|BUTTON_REL, BUTTON_HOME }, - { ACTION_STD_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT}, + { ACTION_STD_CANCEL, BUTTON_DOWN, BUTTON_NONE }, + { ACTION_REC_NEWFILE, BUTTON_HOME|BUTTON_REPEAT, BUTTON_HOME }, + { ACTION_STD_MENU, BUTTON_HOME|BUTTON_REL, BUTTON_NONE}, { ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE }, { ACTION_SETTINGS_INCREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE }, @@ -224,18 +221,22 @@ { ACTION_STD_PREV, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_STD_NEXT, BUTTON_SCROLL_FWD, BUTTON_NONE }, { ACTION_STD_NEXT, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_NONE, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, + { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_recscreen */ - +#endif /** FM Radio Screen **/ static const struct button_mapping button_context_radio[] = { - { ACTION_FM_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_FM_MENU, BUTTON_HOME|BUTTON_REL, BUTTON_NONE }, { ACTION_FM_PRESET, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE }, - { ACTION_FM_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_NONE }, - { ACTION_FM_MODE, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP }, + { ACTION_FM_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_NONE }, + { ACTION_FM_MODE, BUTTON_UP|BUTTON_REPEAT, BUTTON_UP }, { ACTION_FM_EXIT, BUTTON_DOWN|BUTTON_REL, BUTTON_NONE }, - { ACTION_FM_PLAY, BUTTON_UP|BUTTON_REL, BUTTON_UP }, + { ACTION_FM_PLAY, BUTTON_UP|BUTTON_REL, BUTTON_UP }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) }; /* button_context_radio */ @@ -250,15 +251,15 @@ { ACTION_KBD_CURSOR_RIGHT, BUTTON_HOME|BUTTON_RIGHT, BUTTON_NONE }, { ACTION_KBD_CURSOR_RIGHT, BUTTON_HOME|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_KBD_UP, BUTTON_SCROLL_BACK, BUTTON_NONE }, - { ACTION_KBD_UP, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_KBD_DOWN, BUTTON_SCROLL_FWD, BUTTON_NONE }, - { ACTION_KBD_DOWN, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_KBD_PAGE_FLIP, BUTTON_HOME|BUTTON_SELECT, BUTTON_HOME }, + { ACTION_KBD_UP, BUTTON_SCROLL_BACK, BUTTON_NONE }, + { ACTION_KBD_UP, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_SCROLL_FWD, BUTTON_NONE }, + { ACTION_KBD_DOWN, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_PAGE_FLIP, BUTTON_HOME|BUTTON_SELECT, BUTTON_HOME }, { ACTION_KBD_BACKSPACE, BUTTON_DOWN, BUTTON_NONE }, { ACTION_KBD_BACKSPACE, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE }, - { ACTION_KBD_SELECT, BUTTON_SELECT, BUTTON_NONE }, - { ACTION_KBD_DONE, BUTTON_UP, BUTTON_NONE }, + { ACTION_KBD_SELECT, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE }, + { ACTION_KBD_DONE, BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_KBD_ABORT, BUTTON_POWER, BUTTON_NONE }, LAST_ITEM_IN_LIST @@ -313,8 +314,10 @@ return button_context_quickscreen; case CONTEXT_PITCHSCREEN: return button_context_pitchscreen; +#ifdef HAVE_RECORDING case CONTEXT_RECSCREEN: return button_context_recscreen; +#endif case CONTEXT_KEYBOARD: return button_context_keyboard; Index: firmware/SOURCES =================================================================== --- firmware/SOURCES (Revision 20122) +++ firmware/SOURCES (Arbeitskopie) @@ -359,6 +359,12 @@ target/arm/as3525/usb-as3525.c target/arm/as3525/dma-pl081.c target/arm/as3525/ascodec-as3525.c +#if defined(SANSA_FUZE) || defined(SANSA_E200V2) +target/arm/as3525/backlight-e200v2-fuze.c +target/arm/as3525/dbop-e200v2-fuze.c +target/arm/as3525/lcd-e200v2-fuze.c +target/arm/as3525/button-e200v2-fuze.c +#endif #ifndef BOOTLOADER drivers/generic_i2c.c target/arm/adc-as3514.c @@ -1106,8 +1112,6 @@ #ifdef SANSA_E200V2 #ifndef SIMULATOR target/arm/as3525/sansa-e200v2/lcd-e200v2.c -target/arm/as3525/sansa-e200v2/button-e200v2.c -target/arm/as3525/backlight-e200v2-fuze.c #ifndef BOOTLOADER target/arm/as3525/powermgmt-as3525.c #endif /* !BOOTLOADER */ @@ -1137,9 +1141,7 @@ #ifdef SANSA_FUZE #ifndef SIMULATOR -target/arm/as3525/sansa-fuze/button-fuze.c target/arm/as3525/sansa-fuze/lcd-fuze.c -target/arm/as3525/backlight-e200v2-fuze.c #ifndef BOOTLOADER target/arm/as3525/powermgmt-as3525.c #endif /* !BOOTLOADER */ Index: firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c =================================================================== --- firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c (Revision 20122) +++ firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c (Arbeitskopie) @@ -32,6 +32,7 @@ #include "font.h" #include "bidi.h" #include "clock-target.h" +#include "dbop-target.h" static bool display_on = false; /* is the display turned on? */ static bool display_flipped = false; @@ -96,61 +97,6 @@ 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 = (1<<18)|(1<<12)|(8<<0); /* short count, 16bit write, read-timing =8 */ - - GPIOB_AFSEL = 0xfc; - GPIOC_AFSEL = 0xff; - - DBOP_TIMPOL_23 = 0x6000e; - DBOP_CTRL = (1<<18)|(1<<16)|(1<<12)|(8<<0);/* short count,write enable, 16bit write, read-timing =8 */ - 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) -{ - fb_data data = value; - - lcd_write_cmd(reg); - lcd_write_data(&data, 1); -} - /*** hardware configuration ***/ void lcd_set_contrast(int val) @@ -179,57 +125,57 @@ flip_lcd(yesno); } -static void lcd_window(int xmin, int ymin, int xmax, int ymax) +void lcd_window(int xmin, int ymin, int xmax, int ymax) { ymin += y_offset; ymax += y_offset; - lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (xmax << 8) | xmin); - lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); - lcd_write_reg(R_RAM_ADDR_SET, (ymin << 8) | xmin); + dbop_write_reg(R_HORIZ_RAM_ADDR_POS, (xmax << 8) | xmin); + dbop_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); + dbop_write_reg(R_RAM_ADDR_SET, (ymin << 8) | xmin); } -static void _display_on(void) +void _display_on(void) { /* Initialisation the display the same way as the original firmware */ - lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscilation */ + dbop_write_reg(R_START_OSC, 0x0001); /* Start Oscilation */ - lcd_write_reg(R_DRV_OUTPUT_CONTROL, 0x011b); /* 220 lines, GS=0, SS=1 */ + dbop_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); + dbop_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); + dbop_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); + dbop_write_reg(R_COMPARE_REG1, 0); + dbop_write_reg(R_COMPARE_REG2, 0); - lcd_write_reg(R_DISP_CONTROL1, 0x0000); /* GON = 0, DTE = 0, D1-0 = 00b */ + dbop_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); + dbop_write_reg(R_DISP_CONTROL2, 0x0203); /* Scan cycle = 0 frames */ - lcd_write_reg(R_DISP_CONTROL3, 0x0000); + dbop_write_reg(R_DISP_CONTROL3, 0x0000); /* 16 clocks */ - lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0000); + dbop_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); + dbop_write_reg(R_EXT_DISP_IF_CONTROL, 0x0000); /* zero everything*/ - lcd_write_reg(R_POWER_CONTROL1, 0x0000); /* STB = 0, SLP = 0 */ + dbop_write_reg(R_POWER_CONTROL1, 0x0000); /* STB = 0, SLP = 0 */ lcd_delay(10); @@ -238,89 +184,59 @@ /* 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); + dbop_write_reg(R_POWER_CONTROL2, 0x0002); /* VRH3-0 = 1000b: Vreg1OUT = REGP * 1.90 */ - lcd_write_reg(R_POWER_CONTROL3, 0x0008); + dbop_write_reg(R_POWER_CONTROL3, 0x0008); lcd_delay(40); - lcd_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG = 0 */ + dbop_write_reg(R_POWER_CONTROL4, 0x0000); /* VCOMG = 0 */ /* This register is unknown */ - lcd_write_reg(0x56, 0x80f); + dbop_write_reg(0x56, 0x80f); - lcd_write_reg(R_POWER_CONTROL1, 0x4140); + dbop_write_reg(R_POWER_CONTROL1, 0x4140); lcd_delay(10); - lcd_write_reg(R_POWER_CONTROL2, 0x0000); - lcd_write_reg(R_POWER_CONTROL3, 0x0013); + dbop_write_reg(R_POWER_CONTROL2, 0x0000); + dbop_write_reg(R_POWER_CONTROL3, 0x0013); lcd_delay(20); - lcd_write_reg(R_POWER_CONTROL4, 0x6d0e); + dbop_write_reg(R_POWER_CONTROL4, 0x6d0e); lcd_delay(20); - lcd_write_reg(R_POWER_CONTROL4, 0x6d0e); + dbop_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); + dbop_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0002); + dbop_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0707); + dbop_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0182); + dbop_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0203); + dbop_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0706); + dbop_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0006); + dbop_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0706); + dbop_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0000); + dbop_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0x030f); + dbop_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0x0f08); - lcd_write_reg(R_GATE_SCAN_POS, 0); - lcd_write_reg(R_VERT_SCROLL_CONTROL, 0); + dbop_write_reg(R_GATE_SCAN_POS, 0); + dbop_write_reg(R_VERT_SCROLL_CONTROL, 0); lcd_window(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); - lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); - lcd_write_reg(R_2ND_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); + dbop_write_reg(R_1ST_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); + dbop_write_reg(R_2ND_SCR_DRV_POS, (LCD_HEIGHT-1) << 8); - lcd_write_reg(R_DISP_CONTROL1, 0x0037); + dbop_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) @@ -367,87 +283,3 @@ (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); - - lcd_busy = true; - /* Set start position and window */ - lcd_window(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); - - lcd_busy = false; -} /* lcd_update */ - - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - const fb_data *ptr; - int ymax, xmax; - - - if (!display_on) - return; - - xmax = x + width; - if (xmax >= LCD_WIDTH) - xmax = LCD_WIDTH - 1; /* Clip right */ - if (x < 0) - x = 0; /* Clip left */ - if (x >= xmax) - return; /* nothing left to do */ - - width = xmax - x + 1; /* Fix width */ - - ymax = y + height; - if (ymax >= LCD_HEIGHT) - ymax = LCD_HEIGHT - 1; /* 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); - lcd_busy = true; - lcd_window(x, y, xmax, ymax); - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - ptr = (fb_data*)&lcd_framebuffer[y][x]; - - do - { - lcd_write_data(ptr, width); - ptr += LCD_WIDTH; - } - while (++y <= ymax); - - lcd_busy = false; -} /* lcd_update_rect */ - -/* writes one read pixel outside the visible area, needed for correct dbop reads */ -bool lcd_button_support(void) -{ - fb_data data = (0xf<<12); - - if (lcd_busy) - return false; - - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); - /* Set start position and window */ - lcd_window(LCD_WIDTH+1, LCD_HEIGHT+1, LCD_WIDTH+2, LCD_HEIGHT+2); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_write_data(&data, 1); - return true; -} Index: firmware/target/arm/as3525/sansa-e200v2/button-target.h =================================================================== --- firmware/target/arm/as3525/sansa-e200v2/button-target.h (Revision 20122) +++ firmware/target/arm/as3525/sansa-e200v2/button-target.h (Arbeitskopie) @@ -31,6 +31,8 @@ void button_init_device(void); int button_read_device(void); +#define QUEUE_SKIP_COUNTER 2 + /* Sandisk Sansa E200 button codes */ /* Main unit's buttons */ @@ -47,6 +49,7 @@ #define BUTTON_MAIN 0x00000fff +#define BUTTON_BIT_15 BUTTON_REC /* No Remote control */ #define BUTTON_REMOTE 0 Index: firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c =================================================================== --- firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c (Revision 20122) +++ firmware/target/arm/as3525/sansa-e200v2/button-e200v2.c (Arbeitskopie) @@ -1,288 +1 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * 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" - -#define WHEEL_REPEAT_INTERVAL 300000 -#define WHEEL_FAST_ON_INTERVAL 20000 -#define WHEEL_FAST_OFF_INTERVAL 60000 -#define WHEELCLICKS_PER_ROTATION 48 /* wheelclicks per full rotation */ - -static short _dbop_din; -/* Clickwheel */ -static unsigned int old_wheel_value = 0; -static unsigned int wheel_repeat = BUTTON_NONE; -static unsigned int wheel_click_count = 0; -static unsigned int wheel_delta = 0; -static int wheel_fast_mode = 0; -static unsigned long last_wheel_usec = 0; -static unsigned long wheel_velocity = 0; -static long last_wheel_post = 0; -static long next_backlight_on = 0; -/* Buttons */ -static bool hold_button = false; -#ifndef BOOTLOADER -static bool hold_button_old = false; -#endif - -extern bool lcd_button_support(void); - -void button_init_device(void) -{ - -} - -bool button_hold(void) -{ - return hold_button; -} - -void clickwheel(unsigned int wheel_value) -{ - static const unsigned char wheel_tbl[2][4] = - { - { 2, 0, 3, 1 }, /* Clockwise rotation */ - { 1, 3, 0, 2 }, /* Counter-clockwise */ - }; - /* Read wheel - * Bits 13 and 14 of DBOP_DIN change as follows: - * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00 - * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00 - */ - - /* did the wheel value change? */ - unsigned int btn = BUTTON_NONE; - if (old_wheel_value == wheel_tbl[0][wheel_value]) - btn = BUTTON_SCROLL_FWD; - else if (old_wheel_value == wheel_tbl[1][wheel_value]) - btn = BUTTON_SCROLL_BACK; - - if (btn != BUTTON_NONE) - { - int repeat = 1; /* assume repeat */ - unsigned long usec = TIMER1_VALUE; /* WAG!!! and it works!!*/ - unsigned v = (usec - last_wheel_usec) & 0x7fffffff; - - v = (v>0) ? 1000000 / v : 0; /* clicks/sec = 1000000 * +clicks/usec */ - v = (v>0xffffff) ? 0xffffff : v; /* limit to 24 bit */ - - /* some velocity filtering to smooth things out */ - wheel_velocity = (7*wheel_velocity + v) / 8; - - if (btn != wheel_repeat) - { - /* direction reversals nullify all fast mode states */ - wheel_repeat = btn; - repeat = - wheel_fast_mode = - wheel_velocity = - wheel_click_count = 0; - } - - if (wheel_fast_mode != 0) - { - /* fast OFF happens immediately when velocity drops below - threshold */ - if (TIME_AFTER(usec, - last_wheel_usec + WHEEL_FAST_OFF_INTERVAL)) - { - /* moving out of fast mode */ - wheel_fast_mode = 0; - /* reset velocity */ - wheel_velocity = 0; - /* wheel_delta is always 1 in slow mode */ - wheel_delta = 1; - } - } - else - { - /* fast ON gets filtered to avoid inadvertent jumps to fast mode */ - if (repeat && wheel_velocity > 1000000/WHEEL_FAST_ON_INTERVAL) - { - /* moving into fast mode */ - wheel_fast_mode = 1 << 31; - wheel_click_count = 0; - wheel_velocity = 1000000/WHEEL_FAST_OFF_INTERVAL; - } - else if (++wheel_click_count < 2) - { - btn = BUTTON_NONE; - } - - /* wheel_delta is always 1 in slow mode */ - wheel_delta = 1; - } - - if (TIME_AFTER(current_tick, next_backlight_on) || - v <= 4) - { - /* poke backlight to turn it on or maintain it no more often - than every 1/4 second*/ - next_backlight_on = current_tick + HZ/4; - backlight_on(); - buttonlight_on(); - reset_poweroff_timer(); - } - - if (btn != BUTTON_NONE) - { - wheel_click_count = 0; - - /* generate repeats if quick enough */ - if (repeat && TIME_BEFORE(usec, - last_wheel_post + WHEEL_REPEAT_INTERVAL)) - btn |= BUTTON_REPEAT; - - last_wheel_post = usec; - - if (queue_empty(&button_queue)) - { - queue_post(&button_queue, btn, wheel_fast_mode | - (wheel_delta << 24) | - wheel_velocity*360/WHEELCLICKS_PER_ROTATION); - /* message posted - reset delta */ - wheel_delta = 1; - } - else - { - /* skipped post - increment delta */ - if (++wheel_delta > 0x7f) - wheel_delta = 0x7f; - } - } - - last_wheel_usec = usec; - } - old_wheel_value = wheel_value; -} - -static short read_dbop(void) -{ - /*write a red pixel */ - if (!lcd_button_support()) - return _dbop_din; - - /* Set up dbop for input */ - while (!(DBOP_STAT & (1<<10))); /* Wait for fifo to empty */ - DBOP_CTRL |= (1<<19); - DBOP_CTRL &= ~(1<<16); /* disable output */ - - DBOP_TIMPOL_01 = 0xe167e167; //11100001011001111110000101100111 - DBOP_TIMPOL_23 = 0xe167006e; //11100001011001110000000001101110 - - DBOP_CTRL |= (1<<15); /* start read */ - while (!(DBOP_STAT & (1<<16))); /* wait for valid data */ - int delay = 50; - while(delay--); /* small delay to set up read */ - - _dbop_din = DBOP_DIN; /* now read dbop & store info*/ - - DBOP_TIMPOL_01 = 0x6e167; - DBOP_TIMPOL_23 = 0xa167e06f; - DBOP_CTRL |= (1<<16); - DBOP_CTRL &= ~(1<<19); - - return _dbop_din; -} - -short button_dbop_data(void) -{ - return _dbop_din; -} - -/* - * Get button pressed from hardware - */ -int button_read_device(void) -{ - int btn = BUTTON_NONE; - /* read buttons from dbop */ - short dbop = read_dbop(); - - /* hold button */ - if(dbop & (1<<12)) - { - hold_button = true; - return btn; - } - else - { - hold_button = false; - } - - if (dbop & (1<<8)) - btn |= BUTTON_POWER; - if (!(dbop & (1<<15))) - btn |= BUTTON_REC; - - /* handle wheel */ - int wheel_value = dbop & (1<<13|1<<14); - wheel_value >>= 13; - clickwheel(wheel_value); - - /* Set afsel, so that we can read our buttons */ - GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); - /* set dir so we can read our buttons (but reset the C pins first) */ - GPIOB_DIR &= ~(1<<4); - GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); - GPIOC_PIN(2) |= (1<<2); - GPIOC_PIN(3) |= (1<<3); - GPIOC_PIN(4) |= (1<<4); - GPIOC_PIN(5) |= (1<<5); - GPIOC_PIN(6) |= (1<<6); - - GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); - - int delay = 50; /* small delay needed to read buttons correctly */ - while(delay--); - - /* direct GPIO connections */ - if (!GPIOC_PIN(2)) - btn |= BUTTON_UP; - if (!GPIOC_PIN(3)) - btn |= BUTTON_LEFT; - if (!GPIOC_PIN(4)) - btn |= BUTTON_SELECT; - if (!GPIOC_PIN(5)) - btn |= BUTTON_RIGHT; - if (!GPIOC_PIN(6)) - btn |= BUTTON_DOWN; - - /* return to settings needed for lcd */ - GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); - GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6); - -#ifndef BOOTLOADER - /* light handling */ - if (hold_button != hold_button_old) - { - hold_button_old = hold_button; - backlight_hold_changed(hold_button); - } -#endif /* BOOTLOADER */ - /* The int_btn variable is set in the button interrupt handler */ - return btn; -} Index: firmware/target/arm/as3525/system-as3525.c =================================================================== --- firmware/target/arm/as3525/system-as3525.c (Revision 20122) +++ firmware/target/arm/as3525/system-as3525.c (Arbeitskopie) @@ -269,7 +269,6 @@ fmradio_i2c_init(); #endif #endif /* !BOOTLOADER */ - #ifdef HAVE_ADJUSTABLE_CPU_FREQ set_cpu_frequency(CPUFREQ_DEFAULT); #endif Index: firmware/target/arm/as3525/debug-as3525.c =================================================================== --- firmware/target/arm/as3525/debug-as3525.c (Revision 20122) +++ firmware/target/arm/as3525/debug-as3525.c (Arbeitskopie) @@ -27,19 +27,12 @@ #include "system.h" #include "sprintf.h" #include "cpu.h" +#include "dbop-target.h" #define _DEBUG_PRINTF(a,varargs...) \ snprintf(buf, sizeof(buf), (a), ##varargs); lcd_puts(0,line++,buf) -/* FIXME: target tree is including ./debug-target.h rather than the one in - * sansa-fuze/, even though deps contains the correct one - * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/ -#if defined(SANSA_FUZE) || defined(SANSA_E200V2) -#define DEBUG_DBOP -short button_dbop_data(void); -#endif - /* TODO */ bool __dbg_hw_info(void) @@ -66,7 +59,7 @@ #ifdef DEBUG_DBOP line++; _DEBUG_PRINTF("[DBOP_DIN]"); - _DEBUG_PRINTF("DBOP_DIN: %4x", button_dbop_data()); + _DEBUG_PRINTF("DBOP_DIN: %4x", dbop_din_data()); #endif lcd_update(); if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) Index: firmware/target/arm/as3525/dbop-target.h =================================================================== --- firmware/target/arm/as3525/dbop-target.h (Revision 0) +++ firmware/target/arm/as3525/dbop-target.h (Revision 0) @@ -0,0 +1,40 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 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. + * + ****************************************************************************/ + +#ifndef _DBOP_TARGET_H_ +#define _DBOP_TARGET_H_ + +#if defined(SANSA_FUZE) || defined(SANSA_E200V2) +typedef unsigned short dbop_data; + +void dbop_init(void); +void dbop_write_cmd(int cmd); +void dbop_write_data(const dbop_data* ptr, int count); +void dbop_write_reg(int reg, dbop_data value); + +/* FIXME: target tree is including ./debug-target.h rather than the one in + * sansa-fuze/, even though deps contains the correct one + * if I put the below into a sansa-fuze/debug-target.h, it doesn't work*/ +dbop_data dbop_read_dbop_din(void); +dbop_data dbop_din_data(void); +#define DEBUG_DBOP +#endif /* defined(SANSA_FUZE) || defined(SANSA_E200V2) */ +#endif /* _DBOP_TARGET_H_ */ Index: firmware/target/arm/as3525/button-e200v2-fuze.c =================================================================== --- firmware/target/arm/as3525/button-e200v2-fuze.c (Revision 0) +++ firmware/target/arm/as3525/button-e200v2-fuze.c (Revision 0) @@ -0,0 +1,275 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 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. + * + ****************************************************************************/ + +/* Basic button driver for the Fuze + * + * TODO: - Get the wheel working with interrupts + * - find that Home button + */ + +#include "system.h" +#include "button.h" +#include "button-target.h" +#include "dbop-target.h" +#include "backlight.h" + + +#define WHEEL_REPEAT_INTERVAL 300000 +#define WHEEL_FAST_ON_INTERVAL 20000 +#define WHEEL_FAST_OFF_INTERVAL 60000 +#define WHEELCLICKS_PER_ROTATION 48 /* wheelclicks per full rotation */ + +/* Buttons */ +static bool hold_button = false; +#ifndef BOOTLOADER +static bool hold_button_old = false; +#endif +static unsigned int wheel_delta = 0; +static int wheel_fast_mode = 0; +static unsigned long last_wheel_usec = 0; +static unsigned long wheel_velocity = 0; +static long last_wheel_post = 0; +void button_init_device(void) +{ +#ifdef SANSA_FUZE + GPIOA_DIR |= (1<<1); + GPIOA_PIN(1) = (1<<1); +#endif +} + + +#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL) + +void scrollwheel(dbop_data dbop) +{ + + /* getting BUTTON_REPEAT works like this: We increment repeat by 2 if the + * wheel was turned, and decrement it by 1 each tick, + * that means: if you change the wheel fast enough, repeat will be >1 and + * we send BUTTON_REPEAT + */ + static unsigned old_wheel_value = 0; + static int repeat = 0; + static unsigned wheel_click_count = 0; + static int wheel_repeat = 0; + /* Read wheel + * Bits 13 and 14 of DBOP_DIN change as follows: + * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00 + * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00 + */ + static const unsigned char wheel_tbl[2][4] = + { + { 2, 0, 3, 1 }, /* Clockwise rotation */ + { 1, 3, 0, 2 }, /* Counter-clockwise */ + }; + + /* did the wheel value change? */ + unsigned wheel_value = (dbop & (1<<13|1<<14))>>13; + unsigned btn = BUTTON_NONE; + + if (old_wheel_value == wheel_tbl[0][wheel_value]) + btn = BUTTON_SCROLL_FWD; + else if (old_wheel_value == wheel_tbl[1][wheel_value]) + btn = BUTTON_SCROLL_BACK; + + if (btn != BUTTON_NONE) + { + unsigned long usec = TIMER1_VALUE; + unsigned v = (usec - last_wheel_usec) & 0x7fffffff; + + v = (v>0) ? 1000000 / v : 0; /* clicks/sec = 1000000 * +clicks/usec */ + v = (v>0xffffff) ? 0xffffff : v; /* limit to 24 bit */ + + /* some velocity filtering to smooth things out */ + wheel_velocity = (7*wheel_velocity + v) / 8; + + if (btn != wheel_repeat) + { + /* direction reversals nullify all fast mode states */ + wheel_repeat = btn; + repeat = + wheel_fast_mode = + wheel_velocity = + wheel_click_count = 0; + } +#if 1 + if (wheel_fast_mode != 0) + { + /* fast OFF happens immediately when velocity drops below + threshold */ + if (TIME_AFTER(usec, + last_wheel_usec + WHEEL_FAST_OFF_INTERVAL)) + { + /* moving out of fast mode */ +/* + wheel_fast_mode = 0; +*/ + /* reset velocity */ + wheel_velocity = 0; + /* wheel_delta is always 1 in slow mode */ + wheel_delta = 1; + } + } + else + { + /* fast ON gets filtered to avoid inadvertent jumps to fast mode */ + if (repeat && wheel_velocity > 1000000/WHEEL_FAST_ON_INTERVAL) + { + /* moving into fast mode */ +/* + wheel_fast_mode = 1 << 31; +*/ + wheel_click_count = 0; + wheel_velocity = 1000000/WHEEL_FAST_OFF_INTERVAL; + } + + /* wheel_delta is always 1 in slow mode */ + wheel_delta = 1; + } +#endif + /* generate repeats if quick enough */ + if (repeat > 0) + btn |= BUTTON_REPEAT; + if (repeat > 15) + wheel_fast_mode = (1<<15); + else + wheel_fast_mode = 0; + + repeat += 2; + last_wheel_post = usec; + + if (queue_empty(&button_queue) && ++wheel_click_count > QUEUE_SKIP_COUNTER) + { + wheel_click_count = 0; + queue_post(&button_queue, btn, wheel_fast_mode | + (wheel_delta << 24) + | wheel_velocity*360/WHEELCLICKS_PER_ROTATION); + /* message posted - reset delta */ + backlight_on(); + buttonlight_on(); + wheel_delta = 1; + } + else + { + /* skipped post - increment delta */ + if (++wheel_delta > 0x7f) + wheel_delta = 0x7f; + } + + last_wheel_usec = usec; + } + if (repeat > 0) + repeat--; + old_wheel_value = wheel_value; +} +#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */ + +bool button_hold(void) +{ + return hold_button; +} + +static int button_gpio(void) +{ + int btn = BUTTON_NONE; + if(hold_button) + return btn; + /* set afsel, so that we can read our buttons */ + GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); + /* set dir so we can read our buttons (but reset the C pins first) */ + GPIOB_DIR &= ~(1<<4); + GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); + GPIOC_PIN(2) = (1<<2); + GPIOC_PIN(3) = (1<<3); + GPIOC_PIN(4) = (1<<4); + GPIOC_PIN(5) = (1<<5); + GPIOC_PIN(6) = (1<<6); + + GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); + + /* small delay needed to read buttons correctly */ + int delay = 0; + while(delay++ < 32); + + /* direct GPIO connections */ + if (!GPIOC_PIN(3)) + btn |= BUTTON_LEFT; + if (!GPIOC_PIN(2)) + btn |= BUTTON_UP; + if (!GPIOC_PIN(6)) + btn |= BUTTON_DOWN; + if (!GPIOC_PIN(5)) + btn |= BUTTON_RIGHT; + if (!GPIOC_PIN(4)) + btn |= BUTTON_SELECT; + /* return to settings needed for lcd */ + GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); + GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6); + + return btn; +} + +/* + * Get button pressed from hardware + */ +int button_read_device(void) +{ + int btn = BUTTON_NONE; + dbop_data dbop = dbop_read_dbop_din(); + static unsigned power_counter = HZ; + /* hold button */ + if(dbop & (1<<12)) + { + power_counter = HZ; + hold_button = true; + } + else + { + /* might wrap, but shouldn't be much of an issue*/ + if (power_counter > 0) + power_counter--; + hold_button = false; +#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) + /* read wheel on bit 13 & 14, but sent to the button queue seperately */ + scrollwheel(dbop); +#endif + /* read power on bit 8, but not if hold button was just released, since + * you basically always hit power due to the slider mechanism after releasing + * hold (wait ~1 sec) */ + if (dbop & (1<<8) && power_counter == 0) + btn |= BUTTON_POWER; + /* read on bit 15, see button-target.h in fuze/e200v2 subdir*/ + if (!(dbop & (1<<15))) + btn |= BUTTON_BIT_15; + btn |= button_gpio(); + } + +#ifndef BOOTLOADER + /* light handling */ + if (hold_button != hold_button_old) + { + hold_button_old = hold_button; + backlight_hold_changed(hold_button); + } +#endif /* BOOTLOADER */ + + return btn; +} Index: firmware/target/arm/as3525/dbop-e200v2-fuze.c =================================================================== --- firmware/target/arm/as3525/dbop-e200v2-fuze.c (Revision 0) +++ firmware/target/arm/as3525/dbop-e200v2-fuze.c (Revision 0) @@ -0,0 +1,149 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 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 +#include "config.h" +#include "cpu.h" +#include "clock-target.h" +#include "dbop-target.h" + +static dbop_data _dbop_din; +/* in the lcd driver */ +extern bool lcd_button_support(void); + +void 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 */ +} + +void dbop_write_cmd(int cmd) +{ + int x; + + /* Write register */ + DBOP_CTRL &= ~(1<<14); + + DBOP_TIMPOL_23 = 0xa167006e; + + DBOP_DOUT = cmd; + + /* Wait for fifo to empty */ + while ((DBOP_STAT & (1<<10)) == 0); + +#ifdef SANSA_FUZE + /* This loop is unique to the Fuze */ + x = 0; + do { + asm volatile ("nop\n"); + } while (x++ < 4); +#endif + + DBOP_TIMPOL_23 = 0xa167e06f; +} + + +void dbop_write_data(const dbop_data* p_bytes, int count) +{ + while (count--) + { + DBOP_DOUT = *p_bytes++; + /* Wait for fifo to empty */ + while ((DBOP_STAT & (1<<10)) == 0); + } +} + +void dbop_write_reg(int reg, dbop_data value) +{ + dbop_data data = value; + dbop_write_cmd(reg); + dbop_write_data(&data, 1); +} + +dbop_data dbop_read_dbop_din(void) +{ + /* For Sansa Fuze: + * skip home and power reading if lcd_button_support was blocked, + * since the dbop bit 15 is invalid then, and use the old value instead + * -20 (arbitary value) indicates valid home&power button read */ + /* For Sansa e200: + * Just skip the whole reading, since the wheel is invalid too */ + int old_home_power = -20; + if(!lcd_button_support()) + { +#ifdef SANSA_E200V2 + (void)old_home_power; + return _dbop_din; +#elif defined(SANSA_FUZE) + old_home_power = (_dbop_din & (1<<15|1<<8)); +#endif + } + + /* Wait for fifo to empty */ + while ((DBOP_STAT & (1<<10)) == 0); + + DBOP_CTRL |= (1<<19); + DBOP_CTRL &= ~(1<<16); /* disable output */ + + DBOP_TIMPOL_01 = 0xe167e167; + DBOP_TIMPOL_23 = 0xe167006e; + + DBOP_CTRL |= (1<<15); /* start read */ + while((DBOP_STAT & (1<<16)) == 0); /* wait for valid data */ + + _dbop_din = DBOP_DIN; /* now read */ + + DBOP_TIMPOL_01 = 0x6e167; + DBOP_TIMPOL_23 = 0xa167e06f; + + DBOP_CTRL |= (1<<16); + DBOP_CTRL &= ~(1<<19); +#ifdef SANSA_FUZE + /* write back old values if blocked */ + if (old_home_power != -20) + { + _dbop_din |= old_home_power & 1<<15; + _dbop_din &= 0xfeff|(old_home_power & 1<<8); + } +#endif + return _dbop_din; +} + +/* for the debug menu */ +dbop_data dbop_din_data(void) +{ + return _dbop_din; +} + Index: firmware/target/arm/as3525/lcd-e200v2-fuze.c =================================================================== --- firmware/target/arm/as3525/lcd-e200v2-fuze.c (Revision 0) +++ firmware/target/arm/as3525/lcd-e200v2-fuze.c (Revision 0) @@ -0,0 +1,136 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2009 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. + * + ****************************************************************************/ + +/* This file contains lcd functions in common between Sansa Fuze and Sansa e200v2 + * There is still device specific lcd-*.c files in their subfolders */ + +#include "config.h" +#include "lcd.h" +#include "dbop-target.h" +#include + +#define R_ENTRY_MODE 0x03 +#define R_RAM_ADDR_SET 0x21 +#define R_WRITE_DATA_2_GRAM 0x22 + +#define R_ENTRY_MODE_HORZ 0x7030 + +static bool lcd_busy = false; + +extern void _display_on(void); +extern void lcd_window(int xmin, int ymin, int xmax, int ymax); + +void lcd_init_device(void) +{ + dbop_init(); + GPIOA_DIR |= (1<<7|1<<5|1<<4|1<<3); + GPIOA_PIN(5) = 0; + GPIOA_PIN(3) = (1<<3); + GPIOA_PIN(4) = 0; + GPIOA_PIN(7) = 0; + GPIOA_PIN(5) = (1<<5); + + _display_on(); +} + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + if (!lcd_enabled()) + return; + + dbop_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + + lcd_busy = true; + /* Set start position and window */ + lcd_window(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1); + + dbop_write_cmd(R_WRITE_DATA_2_GRAM); + + dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); + + lcd_busy = false; +} /* lcd_update */ + + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) +{ + const dbop_data *ptr; + int ymax, xmax; + + + if (!lcd_enabled()) + return; + + xmax = x + width; + if (xmax >= LCD_WIDTH) + xmax = LCD_WIDTH - 1; /* Clip right */ + if (x < 0) + x = 0; /* Clip left */ + if (x >= xmax) + return; /* nothing left to do */ + + width = xmax - x + 1; /* Fix width */ + + ymax = y + height; + if (ymax >= LCD_HEIGHT) + ymax = LCD_HEIGHT - 1; /* Clip bottom */ + if (y < 0) + y = 0; /* Clip top */ + if (y >= ymax) + return; /* nothing left to do */ + + dbop_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + lcd_busy = true; + lcd_window(x, y, xmax, ymax); + dbop_write_cmd(R_WRITE_DATA_2_GRAM); + + ptr = (dbop_data*)&lcd_framebuffer[y][x]; + + do + { + dbop_write_data(ptr, width); + ptr += LCD_WIDTH; + } + while (++y <= ymax); + + lcd_busy = false; +} /* lcd_update_rect */ + +/* writes one read pixel outside the visible area, needed for correct dbop reads */ +bool lcd_button_support(void) +{ + dbop_data data = (0xf<<12); + + if (lcd_busy) + return false; + + dbop_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + /* Set start position and window */ + lcd_window(-1, -1, 1, 1); + + dbop_write_cmd(R_WRITE_DATA_2_GRAM); + + dbop_write_data(&data, 1); + return true; +} Index: firmware/target/arm/as3525/sansa-fuze/button-fuze.c =================================================================== --- firmware/target/arm/as3525/sansa-fuze/button-fuze.c (Revision 20122) +++ firmware/target/arm/as3525/sansa-fuze/button-fuze.c (Arbeitskopie) @@ -1,259 +1 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2008 by Thomas Martitz - * Copyright (C) 2008 by Dominik Wenger - * - * 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. - * - ****************************************************************************/ - -/* Basic button driver for the Fuze - * - * TODO: - Get the wheel working with interrupts - * - find that Home button - */ - -#include "system.h" -#include "button.h" -#include "button-target.h" -#include "backlight.h" - -#define WHEEL_REPEAT_INTERVAL 30 -#define WHEELCLICKS_PER_ROTATION 48 /* wheelclicks per full rotation */ - -/* Buttons */ -static bool hold_button = false; -#ifndef BOOTLOADER -static bool hold_button_old = false; -#endif -static short _dbop_din = BUTTON_NONE; - -/* in the lcd driver */ -extern bool lcd_button_support(void); - -void button_init_device(void) -{ - GPIOA_DIR |= (1<<1); - GPIOA_PIN(1) = (1<<1); -} - -#if !defined(BOOTLOADER) && defined(HAVE_SCROLLWHEEL) -static void scrollwheel(void) -{ - static unsigned old_wheel_value = 0; - static unsigned wheel_value = 0; - static unsigned wheel_repeat = BUTTON_NONE; - unsigned btn = BUTTON_NONE; - /* getting BUTTON_REPEAT works like this: We increment repeat by 2 if the - * wheel was turned, and decrement it by 1 each tick, - * that means: if you change the wheel fast enough, repeat will be >1 and - * we send BUTTON_REPEAT - */ - static int repeat = 0; - /* we omit 3 of 4 posts to the button_queue, that works better, so count */ - static int counter = 0; - /* Read wheel - * Bits 13 and 14 of DBOP_DIN change as follows: - * Clockwise rotation 00 -> 01 -> 11 -> 10 -> 00 - * Counter-clockwise 00 -> 10 -> 11 -> 01 -> 00 - */ - static const unsigned char wheel_tbl[2][4] = - { - { 2, 0, 3, 1 }, /* Clockwise rotation */ - { 1, 3, 0, 2 }, /* Counter-clockwise */ - }; - wheel_value = _dbop_din & (1<<13|1<<14); - wheel_value >>= 13; - - if (old_wheel_value == wheel_tbl[0][wheel_value]) - btn = BUTTON_SCROLL_FWD; - else if (old_wheel_value == wheel_tbl[1][wheel_value]) - btn = BUTTON_SCROLL_BACK; - - if (btn != BUTTON_NONE) - { - if (btn != wheel_repeat) - { - /* direction reversals nullify repeats */ - wheel_repeat = btn; - repeat = 0; - } - if (btn != BUTTON_NONE) - { - /* generate repeats if quick enough */ - if (repeat > 0) - { - btn |= BUTTON_REPEAT; - } - repeat += 2; - /* the wheel is more reliable if we don't send ever change, - * every 4th is basically one "physical click" is 1 item in - * the rockbox menus */ - if (queue_empty(&button_queue) && ++counter >= 4) - { - buttonlight_on(); - backlight_on(); - queue_post(&button_queue, btn, 1<<24); - /* message posted - reset count */ - counter = 0; - } - } - } - if (repeat > 0) - repeat--; - else - repeat = 0; - old_wheel_value = wheel_value; -} -#endif /* !defined(BOOTLOADER) && defined(SCROLLWHEEL) */ - -bool button_hold(void) -{ - return hold_button; -} - -static short button_dbop(void) -{ - /* skip home and power reading if lcd_button_support was blocked, - * since the dbop bit 15 is invalid then, and use the old value instead */ - /* -20 (arbitary value) indicates valid home&power button read */ - int old_home_power = -20; - if(!lcd_button_support()) - { - old_home_power = (_dbop_din & (1<<15|1<<8)); - } - - /* Wait for fifo to empty */ - while ((DBOP_STAT & (1<<10)) == 0); - - DBOP_CTRL |= (1<<19); - DBOP_CTRL &= ~(1<<16); /* disable output */ - - DBOP_TIMPOL_01 = 0xe167e167; - DBOP_TIMPOL_23 = 0xe167006e; - - DBOP_CTRL |= (1<<15); /* start read */ - while((DBOP_STAT & (1<<16)) == 0); /* wait for valid data */ - - _dbop_din = DBOP_DIN; /* now read */ - - DBOP_TIMPOL_01 = 0x6e167; - DBOP_TIMPOL_23 = 0xa167e06f; - - DBOP_CTRL |= (1<<16); - DBOP_CTRL &= ~(1<<19); - - /* write back old values if blocked */ - if (old_home_power != -20) - { - _dbop_din |= old_home_power & 1<<15; - _dbop_din &= 0xfeff|(old_home_power & 1<<8); - } - return _dbop_din; -} - -/* for the debug menu */ -short button_dbop_data(void) -{ - return _dbop_din; -} - -static int button_gpio(void) -{ - int btn = BUTTON_NONE; - if(hold_button) - return btn; - /* set afsel, so that we can read our buttons */ - GPIOC_AFSEL &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); - /* set dir so we can read our buttons (but reset the C pins first) */ - GPIOB_DIR &= ~(1<<4); - GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); - GPIOC_PIN(2) = (1<<2); - GPIOC_PIN(3) = (1<<3); - GPIOC_PIN(4) = (1<<4); - GPIOC_PIN(5) = (1<<5); - GPIOC_PIN(6) = (1<<6); - - GPIOC_DIR &= ~(1<<2|1<<3|1<<4|1<<5|1<<6); - - /* small delay needed to read buttons correctly */ - int delay = 0; - while(delay++ < 32); - - /* direct GPIO connections */ - if (!GPIOC_PIN(3)) - btn |= BUTTON_LEFT; - if (!GPIOC_PIN(2)) - btn |= BUTTON_UP; - if (!GPIOC_PIN(6)) - btn |= BUTTON_DOWN; - if (!GPIOC_PIN(5)) - btn |= BUTTON_RIGHT; - if (!GPIOC_PIN(4)) - btn |= BUTTON_SELECT; - /* return to settings needed for lcd */ - GPIOC_DIR |= (1<<2|1<<3|1<<4|1<<5|1<<6); - GPIOC_AFSEL |= (1<<2|1<<3|1<<4|1<<5|1<<6); - - return btn; -} - -/* - * Get button pressed from hardware - */ -int button_read_device(void) -{ - int btn = BUTTON_NONE; - short dbop = button_dbop(); - static unsigned power_counter = HZ; - /* hold button */ - if(dbop & (1<<12)) - { - power_counter = 0; - hold_button = true; - } - else - { - /* might wrap, but shouldn't be much of an issue*/ - power_counter++; - hold_button = false; -#if defined(HAVE_SCROLLWHEEL) && !defined(BOOTLOADER) - /* read wheel on bit 13 & 14, but sent to the button queue seperately */ - scrollwheel(); -#endif - /* read power on bit 8, but not if hold button was just released, since - * you basically always hit power due to the slider mechanism after releasing - * hold (wait ~1 sec) */ - if (dbop & (1<<8) && power_counter>HZ) - btn |= BUTTON_POWER; - /* read home on bit 15 */ - if (!(dbop & (1<<15))) - btn |= BUTTON_HOME; - btn |= button_gpio(); - } - -#ifndef BOOTLOADER - /* light handling */ - if (hold_button != hold_button_old) - { - hold_button_old = hold_button; - backlight_hold_changed(hold_button); - } -#endif /* BOOTLOADER */ - - return btn; -} Index: firmware/target/arm/as3525/sansa-fuze/button-target.h =================================================================== --- firmware/target/arm/as3525/sansa-fuze/button-target.h (Revision 20122) +++ firmware/target/arm/as3525/sansa-fuze/button-target.h (Arbeitskopie) @@ -26,11 +26,13 @@ #include "config.h" #define HAS_BUTTON_HOLD +#define QUEUE_SKIP_COUNTER 4 void button_init_device(void); bool button_hold(void); int button_read_device(void); + /* Sandisk Sansa Fuze button codes */ /* Main unit's buttons */ @@ -54,6 +56,7 @@ |BUTTON_SCROLL_BACK|BUTTON_SCROLL_FWD| \ |BUTTON_HOLD) +#define BUTTON_BIT_15 BUTTON_HOME /* No Remote control */ #define BUTTON_REMOTE 0 Index: firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c =================================================================== --- firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Revision 20122) +++ firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Arbeitskopie) @@ -20,18 +20,17 @@ * KIND, either express or implied. * ****************************************************************************/ -#include "config.h" +#include "config.h" #include "cpu.h" #include "lcd.h" -#include "file.h" -#include "debug.h" -#include "system.h" -#include "clock-target.h" +#include "dbop-target.h" /* The controller is unknown, but some registers appear to be the same as the HD66789R */ +extern void lcd_update(void); + #define R_ENTRY_MODE 0x03 #define R_RAM_ADDR_SET 0x21 #define R_WRITE_DATA_2_GRAM 0x22 @@ -46,68 +45,6 @@ * so block lcd_button_support the during updates */ static volatile bool lcd_busy = false; -static void as3525_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) -{ - int x; - - /* Write register */ - DBOP_CTRL &= ~(1<<14); - - DBOP_TIMPOL_23 = 0xa167006e; - - DBOP_DOUT = cmd; - - /* Wait for fifo to empty */ - while ((DBOP_STAT & (1<<10)) == 0); - - /* This loop is unique to the Fuze */ - x = 0; - do { - asm volatile ("nop\n"); - } while (x++ < 4); - - - 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) @@ -137,50 +74,71 @@ } -static void _display_on(void) +/* Set horizontal window addresses */ +void lcd_window_x(int xmin, int xmax) { - /* Initialise in the same way as the original firmare */ + xmin += xoffset; + xmax += xoffset; + dbop_write_reg(0x46, (xmax << 8) | xmin); + dbop_write_reg(0x20, xmin); +} - lcd_write_reg(0x07, 0); - lcd_write_reg(0x13, 0); +/* Set vertical window addresses */ +void lcd_window_y(int ymin, int ymax) +{ + dbop_write_reg(0x47, ymax); + dbop_write_reg(0x48, ymin); + dbop_write_reg(0x21, ymin); +} - lcd_write_reg(0x11, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(0x10, 0x3860); - lcd_write_reg(0x13, 0x40); +void lcd_window(int xmin, int ymin, int xmax, int ymax) +{ + lcd_window_x(xmin, xmax); + lcd_window_y(ymin, ymax); +} - lcd_write_reg(0x13, 0x60); +void _display_on(void) +{ + /* Initialise in the same way as the original firmare */ - lcd_write_reg(0x13, 0x70); - lcd_write_reg(0x01, 277); - lcd_write_reg(0x02, (7<<8)); - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); - lcd_write_reg(0x08, 0x01); - lcd_write_reg(0x0b, (1<<10)); - lcd_write_reg(0x0c, 0); + dbop_write_reg(0x07, 0); + dbop_write_reg(0x13, 0); - lcd_write_reg(0x30, 0x40); - lcd_write_reg(0x31, 0x0687); - lcd_write_reg(0x32, 0x0306); - lcd_write_reg(0x33, 0x104); - lcd_write_reg(0x34, 0x0585); - lcd_write_reg(0x35, 255+66); - lcd_write_reg(0x36, 0x0687+128); - lcd_write_reg(0x37, 259); - lcd_write_reg(0x38, 0); - lcd_write_reg(0x39, 0); + dbop_write_reg(0x11, 0x3704); + dbop_write_reg(0x14, 0x1a1b); + dbop_write_reg(0x10, 0x3860); + dbop_write_reg(0x13, 0x40); - lcd_write_reg(0x42, (LCD_WIDTH - 1)); - lcd_write_reg(0x43, 0); - lcd_write_reg(0x44, (LCD_WIDTH - 1)); - lcd_write_reg(0x45, 0); - lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); - lcd_write_reg(0x47, (LCD_HEIGHT - 1)); - lcd_write_reg(0x48, 0x0); + dbop_write_reg(0x13, 0x60); - lcd_write_reg(0x07, 0x11); - lcd_write_reg(0x07, 0x17); + dbop_write_reg(0x13, 0x70); + dbop_write_reg(0x01, 277); + dbop_write_reg(0x02, (7<<8)); + dbop_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); + dbop_write_reg(0x08, 0x01); + dbop_write_reg(0x0b, (1<<10)); + dbop_write_reg(0x0c, 0); + dbop_write_reg(0x30, 0x40); + dbop_write_reg(0x31, 0x0687); + dbop_write_reg(0x32, 0x0306); + dbop_write_reg(0x33, 0x104); + dbop_write_reg(0x34, 0x0585); + dbop_write_reg(0x35, 255+66); + dbop_write_reg(0x36, 0x0687+128); + dbop_write_reg(0x37, 259); + dbop_write_reg(0x38, 0); + dbop_write_reg(0x39, 0); + + dbop_write_reg(0x42, (LCD_WIDTH - 1)); + dbop_write_reg(0x43, 0); + dbop_write_reg(0x44, (LCD_WIDTH - 1)); + dbop_write_reg(0x45, 0); + lcd_window(0, 0, LCD_WIDTH-1, LCD_WIDTH-1); + + dbop_write_reg(0x07, 0x11); + dbop_write_reg(0x07, 0x17); + display_on = true; /* must be done before calling lcd_update() */ lcd_update(); } @@ -192,16 +150,16 @@ if(on) { int delay = 0x200000; - lcd_write_reg(0, 1); - lcd_write_reg(0x10, 0); - lcd_write_reg(0x11, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(0x10, 0x3860); - lcd_write_reg(0x13, 0x40); - lcd_write_reg(0x13, 0x60); - lcd_write_reg(0x13, 112); - lcd_write_reg(0x07, 0x11); - lcd_write_reg(0x07, 0x17); + dbop_write_reg(0, 1); + dbop_write_reg(0x10, 0); + dbop_write_reg(0x11, 0x3704); + dbop_write_reg(0x14, 0x1a1b); + dbop_write_reg(0x10, 0x3860); + dbop_write_reg(0x13, 0x40); + dbop_write_reg(0x13, 0x60); + dbop_write_reg(0x13, 112); + dbop_write_reg(0x07, 0x11); + dbop_write_reg(0x07, 0x17); display_on = true; /* a bit of delay before returning to * avoid irritating flash on backlight on */ @@ -210,9 +168,9 @@ } else { - lcd_write_reg(0x07, 0x22); - lcd_write_reg(0x07, 0); - lcd_write_reg(0x10, 1); + dbop_write_reg(0x07, 0x22); + dbop_write_reg(0x07, 0); + dbop_write_reg(0x10, 1); display_on = false; } } @@ -246,119 +204,3 @@ (void)width; (void)height; } - -void lcd_init_device() -{ - as3525_dbop_init(); - - GPIOA_DIR |= (1<<7|1<<5|1<<4|1<<3); - GPIOA_PIN(5) = 0; - GPIOA_PIN(3) = (1<<3); - GPIOA_PIN(4) = 0; - GPIOA_PIN(7) = 0; - GPIOA_PIN(5) = (1<<5); - - _display_on(); -} - -/* Set horizontal window addresses */ -void lcd_window_x(int xmin, int xmax) -{ - xmin += xoffset; - xmax += xoffset; - lcd_write_reg(0x46, (xmax << 8) | xmin); - lcd_write_reg(0x20, xmin); -} - -/* Set vertical window addresses */ -void lcd_window_y(int ymin, int ymax) -{ - lcd_write_reg(0x47, ymax); - lcd_write_reg(0x48, ymin); - lcd_write_reg(0x21, ymin); -} - -/* 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); - - lcd_busy = true; - lcd_window_x(0, LCD_WIDTH - 1); - lcd_window_y(0, LCD_HEIGHT - 1); - - /* Start write to GRAM */ - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - /* Write data */ - lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); - lcd_busy = false; -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - int xmax, ymax; - const unsigned short *ptr; - - if (!display_on) - return; - - xmax = x + width; - if (xmax >= LCD_WIDTH) - xmax = LCD_WIDTH - 1; /* Clip right */ - if (x < 0) - x = 0; /* Clip left */ - if (x >= xmax) - return; /* nothing left to do */ - - width = xmax - x + 1; /* Fix width */ - - ymax = y + height; - if (ymax >= LCD_HEIGHT) - ymax = LCD_HEIGHT - 1; /* 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); - - lcd_busy = true; - lcd_window_x(x, xmax); - lcd_window_y(y, ymax); - - /* Start write to GRAM */ - 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_busy = false; -} - -/* writes one read pixel outside the visible area, needed for correct dbop reads */ -bool lcd_button_support(void) -{ - fb_data data = 0xf<<12; - if (lcd_busy) - return false; - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ); - /* Set start position and window */ - - lcd_window_x(-1, 1); - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_write_data(&data, 1); - - return true; -}