From 173b611921db2d353d977dc617a8288345f5e6ed Mon Sep 17 00:00:00 2001 From: Karl Kurbjun Date: Mon, 7 May 2007 19:34:34 +0000 Subject: Basic gigabeat buttonlight support outside of debug menu FS#7112. Also disables USB PLL and the USB device clock (uneeded to connect to computer) - May offer some power savings. Changed how some pins are initialized. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13346 a1c6a512-1295-4272-9138-f99709370657 --- apps/debug_menu.c | 160 +---- apps/lang/english.lang | 6 +- apps/settings_list.c | 2 +- firmware/backlight.c | 3 +- firmware/drivers/power.c | 14 - firmware/drivers/rtc/rtc_s3c2440.c | 12 +- firmware/export/config-gigabeat.h | 4 +- .../target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c | 10 +- .../arm/s3c2440/gigabeat-fx/backlight-meg-fx.c | 679 +++++---------------- .../arm/s3c2440/gigabeat-fx/backlight-target.h | 42 +- .../target/arm/s3c2440/gigabeat-fx/button-meg-fx.c | 14 +- .../target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c | 201 +++--- .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 7 +- .../target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c | 12 +- 14 files changed, 299 insertions(+), 867 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 0176b7405d..9e654b1d45 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -1132,7 +1132,7 @@ bool dbg_ports(void) return false; } #elif CONFIG_CPU == S3C2440 - char buf[128]; + char buf[50]; int line; lcd_setmargins(0, 0); @@ -1142,28 +1142,36 @@ bool dbg_ports(void) while(1) { line = 0; - snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); - - snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); - - snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf); - - snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "[Ports and Registers]"); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf); + line++; + + snprintf(buf, sizeof(buf), "SRCPND: %08x INTMOD: %08x", SRCPND, INTMOD); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "INTMSK: %08x INTPND: %08x", INTMSK, INTPND); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "CLKCON: %08x CLKSLOW: %08x", CLKCON, CLKSLOW); lcd_puts(0, line++, buf); lcd_update(); if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) return false; @@ -2093,112 +2101,6 @@ static bool dbg_lcd_power_off(void) } return false; } - -#include "backlight-target.h" - -static bool dbg_buttonlights(void) -{ - unsigned short mode_changed = 1, mode = 0; - enum buttonlight_selection which_led = BUTTONLIGHT_LED_ALL; - unsigned short brightness = DEFAULT_BRIGHTNESS_SETTING; - - lcd_setmargins(0, 0); - for (;;) - { - int button; - - if (mode_changed) - { - lcd_clear_display(); - lcd_puts(0, 0, "Button light support"); - lcd_puts(0, 1, "Press UP for mode change"); - lcd_puts(0, 2, "Press DOWN for buttonlight selection"); - - switch (mode) - { - case 0: - lcd_puts(1, 3, "Off"); - __buttonlight_mode(BUTTONLIGHT_OFF, which_led, brightness); - break; - - case 1: - lcd_puts(1, 3, "On - Set to brightness"); - __buttonlight_mode(BUTTONLIGHT_ON, which_led, brightness); - break; - - case 2: - lcd_puts(1, 3, "Faint - Always on at lowest brightness"); - __buttonlight_mode(BUTTONLIGHT_FAINT, which_led, brightness); - break; - - case 3: - lcd_puts(1, 3, "Flicker on disk access"); - __buttonlight_mode(BUTTONLIGHT_FLICKER, which_led, brightness); - break; - - case 4: - lcd_puts(1, 3, "Solid on disk access"); - __buttonlight_mode(BUTTONLIGHT_SIGNAL, which_led, brightness); - break; - - case 5: - lcd_puts(1, 3, "Follows backlight"); - __buttonlight_mode(BUTTONLIGHT_FOLLOW, which_led, brightness); - break; - - case 6: - lcd_puts(1, 3, "Shows 'battery charging'"); - __buttonlight_mode(BUTTONLIGHT_CHARGING, which_led, brightness); - break; - - } - mode_changed = 0; - lcd_update(); - } - - - - /* does nothing unless in flicker mode */ - /* the parameter sets the brightness */ - __buttonlight_trigger(); - button = get_action(CONTEXT_STD,HZ/5); - switch(button) - { - case ACTION_STD_PREV: - if (++mode > 6) mode = 0; - mode_changed = 1; - break; - - case ACTION_STD_NEXT: - if (which_led == BUTTONLIGHT_LED_ALL) - { - which_led = BUTTONLIGHT_LED_MENU; - } - else - { - which_led = BUTTONLIGHT_LED_ALL; - } - mode_changed = 1; - - break; - - - case ACTION_STD_OK: - case ACTION_STD_CANCEL: - action_signalscreenchange(); - return false; - - default: - sleep(HZ/10); - break; - } - } - return false; -} - - - - #endif #if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) @@ -2302,8 +2204,6 @@ struct the_menu_item { static const struct the_menu_item menuitems[] = { #if defined(TOSHIBA_GIGABEAT_F) && !defined(SIMULATOR) { "LCD Power Off", dbg_lcd_power_off }, - { "Button Light modes", dbg_buttonlights }, - #endif #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || \ (defined(CPU_PP) && !defined(SANSA_E200)) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 35583e5ddd..8caad6eb9b 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -10760,15 +10760,15 @@ desc: in settings_menu user: - *: "" + *: "Button Light Timeout" e200: "Wheel Light Timeout" - *: "" + *: "Button Light Timeout" e200: "Wheel Light Timeout" - *: "" + *: "Button Light Timeout" e200: "Wheel Light Timeout" diff --git a/apps/settings_list.c b/apps/settings_list.c index dfb7c4ba08..e781c51be0 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -542,7 +542,7 @@ const struct settings_list settings[] = { /* backlight fading */ STRINGCHOICE_SETTING(0,backlight_fade_in, LANG_BACKLIGHT_FADE_IN, 1, "backlight fade in","off,500ms,1s,2s", backlight_set_fade_in, 4, - LANG_OFF, TALK_ID(500, UNIT_MS), + LANG_OFF, TALK_ID(500, UNIT_MS), TALK_ID(1, UNIT_SEC), TALK_ID(2, UNIT_SEC)), STRINGCHOICE_SETTING(0,backlight_fade_out, LANG_BACKLIGHT_FADE_OUT, 1, "backlight fade out","off,500ms,1s,2s,3s,5s,10s", backlight_set_fade_out, 7, diff --git a/firmware/backlight.c b/firmware/backlight.c index 2bdfe86c77..85e3d409b6 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -124,8 +124,7 @@ void button_backlight_set_timeout(int index) else if (index == 1) /* on */ button_backlight_on(); - if (button_backlight_timer) - button_backlight_timer = button_backlight_timeout; + button_backlight_timer = button_backlight_timeout; } /* internal interface */ diff --git a/firmware/drivers/power.c b/firmware/drivers/power.c index 2a87cad2e1..eb69fcec27 100644 --- a/firmware/drivers/power.c +++ b/firmware/drivers/power.c @@ -91,8 +91,6 @@ bool charger_inserted(void) #elif defined (HAVE_FMADC) /* FM or V2, can also charge from the USB port */ return (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF); -#elif defined(TOSHIBA_GIGABEAT_F) - return false; #else /* Player */ return (PADR & 1) == 0; @@ -136,9 +134,6 @@ void ide_power_enable(bool on) { (void)on; -#if defined(TOSHIBA_GIGABEAT_F) - /* Gigabeat TODO */ -#else /* SH1 based archos */ bool touched = false; #ifdef NEEDS_ATA_POWER_ON if(on) @@ -175,15 +170,11 @@ void ide_power_enable(bool on) PACR2 &= 0xFBFF; /* GPIO for PA5 */ #endif } -#endif /* SH1 based archos */ } bool ide_powered(void) { -#if defined(TOSHIBA_GIGABEAT_F) - return false; -#else /* SH1 based archos */ #if defined(NEEDS_ATA_POWER_ON) || defined(HAVE_ATA_POWER_OFF) #ifdef ATA_POWER_PLAYERSTYLE /* This is not correct for very old players, since these are unable to @@ -202,7 +193,6 @@ bool ide_powered(void) #else /* !defined(NEEDS_ATA_POWER_ON) && !defined(HAVE_ATA_POWER_OFF) */ return true; /* pretend always powered if not controlable */ #endif -#endif } #endif /* !HAVE_MMC */ @@ -210,9 +200,6 @@ bool ide_powered(void) void power_off(void) { set_irq_level(HIGHEST_IRQ_LEVEL); -#if defined(TOSHIBA_GIGABEAT_F) - /* FIXME: Can we turn the device off, or only enter sleep mode? */ -#else #ifdef HAVE_POWEROFF_ON_PBDR and_b(~0x10, &PBDRL); or_b(0x10, &PBIORL); @@ -225,7 +212,6 @@ void power_off(void) and_b(~0x08, &PADRH); or_b(0x08, &PAIORH); -#endif #endif while(1) yield(); diff --git a/firmware/drivers/rtc/rtc_s3c2440.c b/firmware/drivers/rtc/rtc_s3c2440.c index ae422ffc2d..b1bc622058 100644 --- a/firmware/drivers/rtc/rtc_s3c2440.c +++ b/firmware/drivers/rtc/rtc_s3c2440.c @@ -21,7 +21,6 @@ #include "rtc.h" #include "kernel.h" #include "system.h" -#include void rtc_init(void) { @@ -55,7 +54,7 @@ int rtc_write_datetime(unsigned char* buf) return 1; } -#ifdef HAVE_RTC_ALARM +#ifdef HAVE_RTC_ALARM /* This alarm code works in that it at least triggers INT_RTC. I am guessing * that the OF bootloader for the Gigabeat detects the startup by alarm and shuts down. * This code is available for use once the OF bootloader is no longer required. @@ -110,13 +109,16 @@ void rtc_get_alarm(int *h, int *m) */ bool rtc_enable_alarm(bool enable) { - /* Note: The interupt for the alarm is normally masked. May want to enable ( INTMSK&=~(1<<30); ) - * it here if an alarm handler is desired (while the unit is not in sleep). - */ if (enable) + { RTCALM=0x46; + INTMSK&=~(1<<30); + } else + { RTCALM=0x00; + INTMSK|=(1<<30); + } return false; /* all ok */ } diff --git a/firmware/export/config-gigabeat.h b/firmware/export/config-gigabeat.h index 35b6175227..a83dc55fd8 100644 --- a/firmware/export/config-gigabeat.h +++ b/firmware/export/config-gigabeat.h @@ -32,7 +32,6 @@ #define LCD_DEPTH 16 /* 65k colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ - #define CONFIG_KEYPAD GIGABEAT_PAD /* Define this if you do software codec */ @@ -44,13 +43,14 @@ /* Define this for LCD backlight available */ #define HAVE_BACKLIGHT +#define HAVE_BUTTON_LIGHT + #define HAVE_LCD_ENABLE #define HAVE_BACKLIGHT_BRIGHTNESS /* Main LCD backlight brightness range and defaults */ #define MIN_BRIGHTNESS_SETTING 0 /* 0.5 mA */ -#define MIN_ACTIVE_BRIGHTNESS_SETTING 16 /* lowest active brightness */ #define MAX_DIM_BRIGHTNESS_SETTING 15 /* highest 'dimness' */ #define MAX_BRIGHTNESS_SETTING 63 /* 32 mA */ #define DEFAULT_BRIGHTNESS_SETTING 39 /* 20 mA */ diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c index 2f28124edf..d33bcaaf6e 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c @@ -18,7 +18,6 @@ ****************************************************************************/ #include "config.h" #include "cpu.h" -#include #include "kernel.h" #include "thread.h" #include "system.h" @@ -48,13 +47,12 @@ void ata_reset(void) /* This function is called before enabling the USB bus */ void ata_enable(bool on) { + GPBCON=( GPBCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ + GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ if(on) USB_ATA_DISABLE; else USB_ATA_ENABLE; - - GPBCON=( GPBCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ - GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ } bool ata_is_coldstart(void) @@ -65,10 +63,10 @@ bool ata_is_coldstart(void) void ata_device_init(void) { - /* ATA reset */ - ATA_RESET_DISABLE; /* Set the pin to disable an active low reset */ GPGCON=( GPGCON&~(1<<21) ) | (1<<20); /* Make the pin an output */ GPGUP |= 1<<10; /* Disable pullup in SOC as we are now driving */ + /* ATA reset */ + ATA_RESET_DISABLE; /* Set the pin to disable an active low reset */ } #if !defined(BOOTLOADER) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c index a1b6a8a583..a8f8ef5d85 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c @@ -25,19 +25,14 @@ #include "sc606-meg-fx.h" #include "power.h" - #define FLICKER_PERIOD 15 #define BUTTONLIGHT_MENU (SC606_LED_B1) #define BUTTONLIGHT_ALL (SC606_LED_B1 | SC606_LED_B2 | SC606_LED_C1 | SC606_LED_C2) static void led_control_service(void); static unsigned short backlight_brightness; -static unsigned short backlight_current; static unsigned short backlight_target; -static unsigned short time_til_fade; -static unsigned short fade_interval; -static unsigned short initial_tick_delay; -static unsigned char backlight_leds; +static unsigned short buttonlight_target; static enum backlight_states { @@ -45,198 +40,95 @@ static enum backlight_states BACKLIGHT_CONTROL_OFF, BACKLIGHT_CONTROL_ON, BACKLIGHT_CONTROL_SET, - BACKLIGHT_CONTROL_FADE_OFF, - BACKLIGHT_CONTROL_FADE_ON, - BACKLIGHT_CONTROL_FADE_ON_FROM_OFF + BACKLIGHT_CONTROL_FADE } backlight_control; - +static enum sc606_states +{ + SC606_CONTROL_IDLE, + SC606_CONTROL_A12, + SC606_CONTROL_B12, + SC606_CONTROL_C12, + SC606_CONTROL_CONF +} sc606_control; enum buttonlight_states { + BUTTONLIGHT_CONTROL_IDLE, + /* turn button lights off */ - BUTTONLIGHT_MODE_OFF_ENTRY, - BUTTONLIGHT_MODE_OFF, + BUTTONLIGHT_CONTROL_OFF, /* turns button lights on to setting */ - BUTTONLIGHT_MODE_ON_ENTRY, - BUTTONLIGHT_MODE_ON, - - /* turns button lights on to minimum */ - BUTTONLIGHT_MODE_FAINT_ENTRY, - BUTTONLIGHT_MODE_FAINT, - - /* allows button lights to flicker when triggered */ - BUTTONLIGHT_MODE_FLICKER_ENTRY, - BUTTONLIGHT_MODE_FLICKER, - BUTTONLIGHT_MODE_FLICKERING, - - /* button lights solid */ - BUTTONLIGHT_MODE_SOLID_ENTRY, - BUTTONLIGHT_MODE_SOLID, - - /* button light charing */ - BUTTONLIGHT_MODE_CHARGING_ENTRY, - BUTTONLIGHT_MODE_CHARGING, - BUTTONLIGHT_MODE_CHARGING_WAIT, - - /* internal use only */ - BUTTONLIGHT_HELPER_SET, - BUTTONLIGHT_HELPER_SET_FINAL, - BUTTONLIGHT_MODE_STOP, - + BUTTONLIGHT_CONTROL_ON, + /* buttonlights follow the backlight settings */ - BUTTONLIGHT_MODE_FOLLOW_ENTRY, - BUTTONLIGHT_MODE_FOLLOW, -}; - - + BUTTONLIGHT_CONTROL_FADE, -static char buttonlight_leds; -static unsigned short buttonlight_setting; -static unsigned short buttonlight_current; -static unsigned char buttonlight_selected; -static enum buttonlight_states buttonlight_state; -static enum buttonlight_states buttonlight_saved_state; -static unsigned short buttonlight_flickering; +} buttonlight_control; static unsigned short buttonlight_trigger_now; -static unsigned short buttonlight_trigger_brightness; - - - -static unsigned short charging_led_index; -static unsigned short buttonlight_charging_counter; #define CHARGING_LED_COUNT 60 unsigned char charging_leds[] = { 0x00, 0x20, 0x38, 0x3C }; - - bool __backlight_init(void) { + backlight_brightness=DEFAULT_BRIGHTNESS_SETTING; backlight_control = BACKLIGHT_CONTROL_IDLE; - backlight_current = DEFAULT_BRIGHTNESS_SETTING; - - buttonlight_state = BUTTONLIGHT_MODE_OFF; + buttonlight_control = BUTTONLIGHT_CONTROL_IDLE; - buttonlight_selected = 0x04; - - /* delay 4 seconds before any fading */ - initial_tick_delay = 400; /* put the led control on the tick list */ tick_add_task(led_control_service); return true; } - - void __backlight_on(void) { - /* now go turn the backlight on */ backlight_control = BACKLIGHT_CONTROL_ON; } - - void __backlight_off(void) { backlight_control = BACKLIGHT_CONTROL_OFF; } - - /* Assumes that the backlight has been initialized */ void __backlight_set_brightness(int brightness) { /* stop the interrupt from messing us up */ backlight_control = BACKLIGHT_CONTROL_IDLE; - - backlight_brightness = brightness + 1; - - /* only set the brightness if it is different from the current */ - if (backlight_brightness != backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_SET; - } + backlight_brightness = brightness; + backlight_control = BACKLIGHT_CONTROL_SET; } - - /* only works if the buttonlight mode is set to triggered mode */ void __buttonlight_trigger(void) { buttonlight_trigger_now = 1; } - - - /* map the mode from the command into the state machine entries */ -void __buttonlight_mode(enum buttonlight_mode mode, - enum buttonlight_selection selection, - unsigned short brightness) +void __buttonlight_mode(enum buttonlight_mode mode) { /* choose stop to setup mode */ - buttonlight_state = BUTTONLIGHT_MODE_STOP; - - - /* clip brightness */ - if (brightness > MAX_BRIGHTNESS_SETTING) - { - brightness = MAX_BRIGHTNESS_SETTING; - } - - brightness++; - - /* Select which LEDs to use */ - switch (selection) - { - case BUTTONLIGHT_LED_ALL: - buttonlight_selected = BUTTONLIGHT_ALL; - break; - - case BUTTONLIGHT_LED_MENU: - buttonlight_selected = BUTTONLIGHT_MENU; - break; - } + buttonlight_control = BUTTONLIGHT_CONTROL_IDLE; /* which mode to use */ switch (mode) { case BUTTONLIGHT_OFF: - buttonlight_state = BUTTONLIGHT_MODE_OFF_ENTRY; + buttonlight_control = BUTTONLIGHT_CONTROL_OFF; break; case BUTTONLIGHT_ON: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; + buttonlight_control = BUTTONLIGHT_CONTROL_ON; break; - - /* faint is just a quick way to set ON to 1 */ - case BUTTONLIGHT_FAINT: - buttonlight_trigger_brightness = 1; - buttonlight_state = BUTTONLIGHT_MODE_ON_ENTRY; - break; - - case BUTTONLIGHT_FLICKER: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_FLICKER_ENTRY; - break; - - case BUTTONLIGHT_SIGNAL: - buttonlight_trigger_brightness = brightness; - buttonlight_state = BUTTONLIGHT_MODE_SOLID_ENTRY; - break; - + case BUTTONLIGHT_FOLLOW: - buttonlight_state = BUTTONLIGHT_MODE_FOLLOW_ENTRY; - break; - - case BUTTONLIGHT_CHARGING: - buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; + buttonlight_control = BUTTONLIGHT_CONTROL_FADE; break; default: @@ -246,16 +138,11 @@ void __buttonlight_mode(enum buttonlight_mode mode, } - - /* * The button lights have 'modes' of operation. Each mode must setup and * execute its own operation - taking care that this is all done in an ISR. - * */ - - /* led_control_service runs in interrupt context - be brief! * This service is called once per interrupt timer tick - 100 times a second. * @@ -265,428 +152,146 @@ void __buttonlight_mode(enum buttonlight_mode mode, * Putting all led servicing in one thread means that we wont step on any * i2c operations - they are all serialized here in the ISR tick. It also * insures that we get called at equal timing for good visual effect. - * - * The buttonlight service runs only after all backlight services have finished. - * Fading the buttonlights is possible, but not recommended because of the - * additional calls needed during the ISR */ static void led_control_service(void) { - if(initial_tick_delay) { - initial_tick_delay--; - return; - } - switch (backlight_control) + static unsigned char + sc606regAval=DEFAULT_BRIGHTNESS_SETTING, + sc606regBval=DEFAULT_BRIGHTNESS_SETTING, + sc606regCval=DEFAULT_BRIGHTNESS_SETTING, + sc606regCONFval=3; + + static bool sc606_changed=true; + + if(sc606_changed==false) { - case BACKLIGHT_CONTROL_IDLE: - switch (buttonlight_state) + switch (backlight_control) { - case BUTTONLIGHT_MODE_STOP: break; - - /* Buttonlight mode: OFF */ - case BUTTONLIGHT_MODE_OFF_ENTRY: - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - buttonlight_state = BUTTONLIGHT_MODE_OFF; - break; - - case BUTTONLIGHT_MODE_OFF: - break; - - - /* button mode: CHARGING - show charging sequence */ - case BUTTONLIGHT_MODE_CHARGING_ENTRY: - /* start turned off */ - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = DEFAULT_BRIGHTNESS_SETTING; - buttonlight_saved_state = BUTTONLIGHT_MODE_CHARGING_WAIT; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - - - case BUTTONLIGHT_MODE_CHARGING: - if (--buttonlight_charging_counter == 0) - { - /* change led */ - if (charging_state()) - { - buttonlight_leds = charging_leds[charging_led_index]; - if (++charging_led_index >= sizeof(charging_leds)) - { - charging_led_index = 0; - } - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - buttonlight_charging_counter = CHARGING_LED_COUNT; - } + case BACKLIGHT_CONTROL_IDLE: + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_OFF: + sc606_changed=true; + sc606regCONFval &= ~0x03; + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_ON: + sc606_changed=true; + sc606regCONFval |= 0x03; + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_SET: + sc606regAval=backlight_brightness; + sc606_changed=true; + backlight_control = BACKLIGHT_CONTROL_ON; + break; + case BACKLIGHT_CONTROL_FADE: + sc606_changed=true; + sc606regCONFval |= 0x03; + /* The SC606 LED driver can set the brightness in 64 steps */ + if(backlight_target==sc606regAval) + if(sc606regAval) + backlight_control = BACKLIGHT_CONTROL_ON; + else + backlight_control = BACKLIGHT_CONTROL_OFF; else - { - buttonlight_state = BUTTONLIGHT_MODE_CHARGING_ENTRY; - } - } - break; - - /* wait for the charget to be plugged in */ - case BUTTONLIGHT_MODE_CHARGING_WAIT: - if (charging_state()) - { - charging_led_index = 0; - buttonlight_charging_counter = CHARGING_LED_COUNT; - buttonlight_state = BUTTONLIGHT_MODE_CHARGING; - } - break; - - - /* Buttonlight mode: FOLLOW - try to stay current with backlight - * since this runs in the idle of the backlight it will not really - * follow in real time - */ - case BUTTONLIGHT_MODE_FOLLOW_ENTRY: - /* case 1 - backlight on, but buttonlight is off */ - if (backlight_current) - { - /* Turn the buttonlights on */ - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = backlight_current; - buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - /* case 2 - backlight off, but buttonlight is on */ - else - { - buttonlight_current = 0; - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_state = BUTTONLIGHT_MODE_FOLLOW; - } - break; - - case BUTTONLIGHT_MODE_FOLLOW: - if (buttonlight_current != backlight_current) - { - /* case 1 - backlight on, but buttonlight is off */ - if (backlight_current) - { - if (0 == buttonlight_current) - { - /* Turn the buttonlights on */ - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = backlight_current; - buttonlight_saved_state = BUTTONLIGHT_MODE_FOLLOW; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - - /* case 2 - backlight off, but buttonlight is on */ + if(backlight_target>sc606regAval) + sc606regAval++; + else + sc606regAval--; + break; + default: + break; + } + switch (buttonlight_control) + { + case BUTTONLIGHT_CONTROL_IDLE: + buttonlight_control=BUTTONLIGHT_CONTROL_IDLE; + break; + case BUTTONLIGHT_CONTROL_OFF: + sc606_changed=true; + sc606regCONFval &= ~0x3C; + buttonlight_control=BUTTONLIGHT_CONTROL_IDLE; + break; + case BUTTONLIGHT_CONTROL_ON: + sc606_changed=true; + sc606regBval=sc606regCval=backlight_brightness; + sc606regCONFval |= 0x3C; + buttonlight_control=BUTTONLIGHT_CONTROL_IDLE; + break; + case BUTTONLIGHT_CONTROL_FADE: + sc606_changed=true; + sc606regCONFval |= 0x3C; + if(buttonlight_target==sc606regBval) + if(sc606regBval) + buttonlight_control = BUTTONLIGHT_CONTROL_ON; + else + buttonlight_control = BUTTONLIGHT_CONTROL_OFF; else - { - buttonlight_current = 0; - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - } - - } - break; - - - - /* Buttonlight mode: ON - stays at the set brightness */ - case BUTTONLIGHT_MODE_ON_ENTRY: - buttonlight_leds = buttonlight_selected; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_ON; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - break; - - case BUTTONLIGHT_MODE_ON: - break; - - - - /* Buttonlight mode: FLICKER */ - case BUTTONLIGHT_MODE_FLICKER_ENTRY: - /* already on? turn it off */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - - /* set the brightness if not already set */ - if (buttonlight_current != buttonlight_trigger_brightness) - { - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_FLICKER; - buttonlight_state = BUTTONLIGHT_HELPER_SET; - } - else buttonlight_state = BUTTONLIGHT_MODE_FLICKER; - break; - - - case BUTTONLIGHT_MODE_FLICKER: - /* wait for the foreground to trigger flickering */ - if (buttonlight_trigger_now) - { - /* turn them on */ - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - - /* reset the trigger and go flicker the LEDs */ - buttonlight_trigger_now = 0; - buttonlight_flickering = FLICKER_PERIOD; - buttonlight_state = BUTTONLIGHT_MODE_FLICKERING; - } - break; - - - case BUTTONLIGHT_MODE_FLICKERING: - /* flicker the LEDs for as long as we get triggered */ - if (buttonlight_flickering) - { - /* turn the leds off if they are on */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } + if(buttonlight_target>sc606regBval) + sc606regCval=++sc606regBval; + else + sc606regCval=--sc606regBval; + break; + default: + break; + } + } - buttonlight_flickering--; - } + switch (sc606_control) + { + case SC606_CONTROL_IDLE: + if(sc606_changed) + sc606_control=SC606_CONTROL_A12; else - { - /* is flickering triggered again? */ - if (!buttonlight_trigger_now) - { - /* completed a cycle - no new triggers - go back and wait */ - buttonlight_state = BUTTONLIGHT_MODE_FLICKER; - } - else - { - /* reset flickering */ - buttonlight_trigger_now = 0; - buttonlight_flickering = FLICKER_PERIOD; - - /* turn buttonlights on */ - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - } + sc606_control=SC606_CONTROL_IDLE; break; - - - /* Buttonlight mode: SIGNAL / SOLID */ - case BUTTONLIGHT_MODE_SOLID_ENTRY: - /* already on? turn it off */ - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - - /* set the brightness if not already set */ - /* temporary save for the next mode - then to do settings */ - buttonlight_setting = buttonlight_trigger_brightness; - buttonlight_saved_state = BUTTONLIGHT_MODE_SOLID; - buttonlight_state = BUTTONLIGHT_HELPER_SET; + case SC606_CONTROL_A12: + sc606_write(SC606_REG_A , sc606regAval); + sc606_control=SC606_CONTROL_B12; break; - - - case BUTTONLIGHT_MODE_SOLID: - /* wait for the foreground to trigger */ - if (buttonlight_trigger_now) - { - /* turn them on if not already on */ - if (0 == buttonlight_current) - { - buttonlight_leds = buttonlight_selected; - buttonlight_current = buttonlight_setting; - sc606_write(SC606_REG_CONF, backlight_leds | buttonlight_leds); - } - - /* reset the trigger */ - buttonlight_trigger_now = 0; - } - else - { - if (buttonlight_current) - { - buttonlight_leds = 0x00; - sc606_write(SC606_REG_CONF, backlight_leds); - buttonlight_current = 0; - } - } + case SC606_CONTROL_B12: + sc606_write(SC606_REG_B , sc606regBval); + sc606_control=SC606_CONTROL_C12; break; - - - /* set the brightness for the buttonlights - takes 2 passes */ - case BUTTONLIGHT_HELPER_SET: - sc606_write(SC606_REG_B, buttonlight_setting-1); - buttonlight_state = BUTTONLIGHT_HELPER_SET_FINAL; + case SC606_CONTROL_C12: + sc606_write(SC606_REG_C , sc606regCval); + sc606_control=SC606_CONTROL_CONF; break; - - case BUTTONLIGHT_HELPER_SET_FINAL: - sc606_write(SC606_REG_C, buttonlight_setting-1); - buttonlight_current = buttonlight_setting; - buttonlight_state = buttonlight_saved_state; + case SC606_CONTROL_CONF: + sc606_write(SC606_REG_CONF , sc606regCONFval); + sc606_changed=false; + sc606_control=SC606_CONTROL_IDLE; break; - - default: + default: + sc606_control=SC606_CONTROL_A12; break; - - } - break; - - - case BACKLIGHT_CONTROL_FADE_ON_FROM_OFF: - backlight_leds = 0x03; - sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); - backlight_control = BACKLIGHT_CONTROL_FADE_ON; - break; - - - case BACKLIGHT_CONTROL_OFF: - backlight_current = 0; - backlight_leds = 0x00; - sc606_write(SC606_REG_CONF, buttonlight_leds); - backlight_control = BACKLIGHT_CONTROL_IDLE; - - break; - - - case BACKLIGHT_CONTROL_ON: - backlight_leds = 0x03; - sc606_write(SC606_REG_CONF, 0x03 | buttonlight_leds); - backlight_current = backlight_brightness; - backlight_control = BACKLIGHT_CONTROL_IDLE; - break; - - - case BACKLIGHT_CONTROL_SET: - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, backlight_brightness-1); - - /* if we were turned off - turn the backlight on */ - if (backlight_current) - { - backlight_current = backlight_brightness; - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - backlight_control = BACKLIGHT_CONTROL_ON; - } - break; - - - case BACKLIGHT_CONTROL_FADE_ON: - if (--time_til_fade) return; - - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, backlight_current++); - - /* have we hit the target? */ - if (backlight_current == backlight_target) - { - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - time_til_fade = fade_interval; - } - break; - - - case BACKLIGHT_CONTROL_FADE_OFF: - if (--time_til_fade) return; - - /* The SC606 LED driver can set the brightness in 64 steps */ - sc606_write(SC606_REG_A, --backlight_current); - - /* have we hit the target? */ - if (backlight_current == backlight_target) - { - if (backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_IDLE; - } - else - { - backlight_control = BACKLIGHT_CONTROL_OFF; - } - - } - else - { - time_til_fade = fade_interval; - } - break; } - - if(backlight_current) + + if(sc606regCONFval&0x03) lcd_enable(true); else lcd_enable(false); } +void __button_backlight_on(void) +{ + buttonlight_control = BUTTONLIGHT_CONTROL_IDLE; + buttonlight_target = backlight_brightness; + buttonlight_control = BUTTONLIGHT_CONTROL_FADE; +} - - +void __button_backlight_off(void) +{ + buttonlight_control = BUTTONLIGHT_CONTROL_IDLE; + buttonlight_target = 0; + buttonlight_control = BUTTONLIGHT_CONTROL_FADE; +} void __backlight_dim(bool dim_now) { - unsigned short target; - /* dont let the interrupt tick happen */ backlight_control = BACKLIGHT_CONTROL_IDLE; - - target = (dim_now == true) ? 0 : backlight_brightness; - - /* only try and fade if the target is different */ - if (backlight_current != target) - { - backlight_target = target; - - if (backlight_current > backlight_target) - { - time_til_fade = fade_interval = 4; - backlight_control = BACKLIGHT_CONTROL_FADE_OFF; - } - else - { - time_til_fade = fade_interval = 1; - if (backlight_current) - { - backlight_control = BACKLIGHT_CONTROL_FADE_ON; - } - else - { - backlight_control = BACKLIGHT_CONTROL_FADE_ON_FROM_OFF; - } - } - } - + backlight_target = (dim_now == true) ? 0 : backlight_brightness; + backlight_control = BACKLIGHT_CONTROL_FADE; } - - diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h index 5f92cee935..401aa9c5e4 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/backlight-target.h @@ -19,18 +19,6 @@ #ifndef BACKLIGHT_TARGET_H #define BACKLIGHT_TARGET_H - -/* select the led */ -enum buttonlight_selection -{ - /* all leds */ - BUTTONLIGHT_LED_ALL, - - /* only the menu/power led (two buttons for one LED) */ - BUTTONLIGHT_LED_MENU -}; - - /* Use these to set the buttonlight mode */ enum buttonlight_mode { @@ -40,47 +28,27 @@ enum buttonlight_mode /* buttonlights always off */ BUTTONLIGHT_OFF, - /* buttonlights always on but set at lowest brightness */ - BUTTONLIGHT_FAINT, - - /* buttonlights flicker when triggered - continues to flicker - * even if the flicker is still asserted. - */ - BUTTONLIGHT_FLICKER, - - /* buttonlights solid for as long as triggered */ - BUTTONLIGHT_SIGNAL, - /* buttonlights follow backlight */ - BUTTONLIGHT_FOLLOW, - - /* buttonlights show battery charging */ - BUTTONLIGHT_CHARGING, + BUTTONLIGHT_FOLLOW }; - /* Call this to flicker or signal the button lights. Only is effective for * modes that take a trigger input. */ void __buttonlight_trigger(void); - -/* select which led to use on the button lights. Other combinations are - * possible, but don't look very good. - */ - /* map the mode from the command into the state machine entries */ /* See enum buttonlight_mode for available functions */ -void __buttonlight_mode(enum buttonlight_mode mode, - enum buttonlight_selection selection, - unsigned short brightness); - +void __buttonlight_mode(enum buttonlight_mode mode); bool __backlight_init(void); void __backlight_on(void); void __backlight_off(void); void __backlight_set_brightness(int val); +void __button_backlight_on(void); +void __button_backlight_off(void); + /* true: backlight fades off - false: backlight fades on */ void __backlight_dim(bool dim); diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c index 71d45c385c..25a69d7630 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/button-meg-fx.c @@ -17,7 +17,6 @@ * ****************************************************************************/ -#include #include "config.h" #include "cpu.h" #include "system.h" @@ -44,24 +43,16 @@ static int const remote_buttons[] = BUTTON_NONE, /* Nothing in the headphone socket */ }; - - - - void button_init_device(void) { /* Power, Remote Play & Hold switch */ } - - inline bool button_hold(void) { return (GPGDAT & (1 << 15)); } - - int button_read_device(void) { int touchpad; @@ -91,6 +82,7 @@ int button_read_device(void) /* if the buttons dont agree twice in a row, then its none */ lastbutton = btn; btn = BUTTON_NONE; + button_backlight_on(); } /* Check for hold first - exit if asserted with no button pressed */ @@ -115,6 +107,7 @@ int button_read_device(void) if (buttons & (1 << 4)) btn |= BUTTON_A; + button_backlight_on(); } /* the touchpad */ @@ -135,13 +128,12 @@ int button_read_device(void) if (touchpad & (1 << 3)) btn |= BUTTON_SELECT; + button_backlight_on(); } return btn; } - - bool headphones_inserted(void) { unsigned short remote_adc = adc_read(ADC_HPREMOTE); diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c index e69eab432a..c207e310d9 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c @@ -1,6 +1,5 @@ #include "config.h" #include "cpu.h" -#include #include "kernel.h" #include "system.h" #include "logf.h" @@ -9,147 +8,132 @@ #define SLAVE_ADDRESS 0xCC -#define SDA_LO (GPHDAT &= ~(1 << 9)) -#define SDA_HI (GPHDAT |= (1 << 9)) -#define SDA_INPUT (GPHCON &= ~(3 << 18)) -#define SDA_OUTPUT (GPHCON |= (1 << 18)) +#define USE_ASM + +/* This I2C driver tristates the outputs instead of driving logic high's */ #define SDA (GPHDAT & (1 << 9)) +#define SDA_LO_OUT (GPHCON |= (1 << 18));(GPHDAT &= ~(1 << 9)); +#define SDA_HI_IN (GPHCON &= ~(3 << 18)) -#define SCL_LO (GPHDAT &= ~(1 << 10)) -#define SCL_HI (GPHDAT |= (1 << 10)) -#define SCL_INPUT (GPHCON &= ~(3 << 20)) -#define SCL_OUTPUT (GPHCON |= (1 << 20)) #define SCL (GPHDAT & (1 << 10)) - -#define SCL_SDA_HI (GPHDAT |= (3 << 9)) - -/* The SC606 can clock at 400KHz: */ -/* Clock period high is 600nS and low is 1300nS */ -/* The high and low times are different enough to need different timings */ -/* cycles delayed = 30 + 7 * loops */ -/* 100MHz = 10nS per cycle: LO:1300nS=130:14 HI:600nS=60:9 */ -/* 300MHz = 3.36nS per cycle: LO:1300nS=387:51 HI:600nS=179:21 */ -#define DELAY_LO do{int x;for(x=51;x;x--);} while (0) -#define DELAY do{int x;for(x=35;x;x--);} while (0) -#define DELAY_HI do{int x;for(x=21;x;x--);} while (0) - - +#define SCL_LO_OUT (GPHCON |= (1 << 20));(GPHDAT &= ~(1 << 10)); +#define SCL_HI_IN (GPHCON &= ~(3 << 20));while(!SCL); + +/* The SC606 can clock at 400KHz: + * Clock period high is 600nS and low is 1300nS + * The high and low times are different enough to need different timings + * cycles delayed = 2 + 4 * loops + * 100MHz = 10nS per cycle: LO:1300nS=130:33 HI:600nS=60:15 + * 300MHz = 3.33nS per cycle: + * LO:1300nS=394:99 + * HI:600nS=182:21 + * MID(50/50):950(1900/2)ns=288:72 + */ + +#ifdef USE_ASM + +#define DELAY_LO 99 +#define DELAY_MID 72 +#define DELAY_HI 46 +/* This delay loop takes 4 cycles/loop to execute plus 2 for setup */ +#define DELAY(dly) \ + asm volatile( "mov r0,%0 \n" \ + "1: \n" \ + "subs r0,r0,#1 \n" \ + "bhi 1b \n" \ + : : "r"((dly)) : "r0" ); + +#else + +#define DELAY_LO 51 +#define DELAY_MID 35 +#define DELAY_HI 21 +#define DELAY(dly) do{int x;for(x=(dly);x;x--);} while (0) + +#endif static void sc606_i2c_start(void) { - SCL_SDA_HI; - DELAY; - SDA_LO; - DELAY; - SCL_LO; -} - -static void sc606_i2c_restart(void) -{ - SCL_SDA_HI; - DELAY; - SDA_LO; - DELAY; - SCL_LO; + SDA_HI_IN; + SCL_HI_IN; + DELAY(DELAY_MID); + SDA_LO_OUT; + DELAY(DELAY_MID); + SCL_LO_OUT; } static void sc606_i2c_stop(void) { - SDA_LO; - SCL_HI; - DELAY_HI; - SDA_HI; + SDA_LO_OUT; + SCL_HI_IN; + DELAY(DELAY_HI); + SDA_HI_IN; } static void sc606_i2c_ack(void) { + SDA_HI_IN; + SCL_HI_IN; - SDA_LO; - SCL_HI; - DELAY_HI; - SCL_LO; + DELAY(DELAY_HI); + SCL_LO_OUT; } - - -static int sc606_i2c_getack(void) +static bool sc606_i2c_getack(void) { - int ret; - - /* Don't need a delay since follows a data bit with a delay on the end */ - SDA_INPUT; /* And set to input */ - DELAY; - SCL_HI; + bool ret; - ret = (SDA != 0); /* ack failed if SDA is not low */ - DELAY_HI; + SDA_HI_IN; + DELAY(DELAY_MID); + SCL_HI_IN; - SCL_LO; - DELAY_LO; + ret = !SDA; - SDA_HI; - SDA_OUTPUT; - DELAY_LO; + SCL_LO_OUT; + DELAY(DELAY_LO); return ret; } - - static void sc606_i2c_outb(unsigned char byte) { int i; /* clock out each bit, MSB first */ - for (i = 0x80; i; i >>= 1) + for ( i=0x80; i; i>>=1 ) { - if (i & byte) - { - SDA_HI; - } + if ( i & byte ) + SDA_HI_IN; else - { - SDA_LO; - } - DELAY; - - SCL_HI; - DELAY_HI; - - SCL_LO; - DELAY_LO; + SDA_LO_OUT; + DELAY(DELAY_MID); + SCL_HI_IN; + DELAY(DELAY_HI); + SCL_LO_OUT; } - - SDA_HI; - } - - static unsigned char sc606_i2c_inb(void) { - int i; - unsigned char byte = 0; - - SDA_INPUT; /* And set to input */ - /* clock in each bit, MSB first */ - for (i = 0x80; i; i >>= 1) { - SCL_HI; - - if (SDA) - byte |= i; - - SCL_LO; - } - SDA_OUTPUT; + int i; + unsigned char byte = 0; - sc606_i2c_ack(); + /* clock in each bit, MSB first */ + SDA_HI_IN; + for ( i=0x80; i; i>>=1 ) + { + SCL_HI_IN; + DELAY(DELAY_HI); + if ( SDA ) + byte |= i; + SCL_LO_OUT; + DELAY(DELAY_LO); + } - return byte; + sc606_i2c_ack(); + return byte; } - - /* returns number of acks that were bad */ int sc606_write(unsigned char reg, unsigned char data) { @@ -163,7 +147,7 @@ int sc606_write(unsigned char reg, unsigned char data) sc606_i2c_outb(reg); x += sc606_i2c_getack(); - sc606_i2c_restart(); + sc606_i2c_start(); sc606_i2c_outb(SLAVE_ADDRESS); x += sc606_i2c_getack(); @@ -176,8 +160,6 @@ int sc606_write(unsigned char reg, unsigned char data) return x; } - - int sc606_read(unsigned char reg, unsigned char* data) { int x; @@ -189,7 +171,7 @@ int sc606_read(unsigned char reg, unsigned char* data) sc606_i2c_outb(reg); x += sc606_i2c_getack(); - sc606_i2c_restart(); + sc606_i2c_start(); sc606_i2c_outb(SLAVE_ADDRESS | 1); x += sc606_i2c_getack(); @@ -199,8 +181,6 @@ int sc606_read(unsigned char reg, unsigned char* data) return x; } - - void sc606_init(void) { volatile int i; @@ -214,12 +194,11 @@ void sc606_init(void) /* About 400us - needs 350us */ for (i = 200; i; i--) - { - DELAY_LO; - } + DELAY(DELAY_LO); /* Set GPH9 (SDA) and GPH10 (SCL) to 1 */ GPHUP &= ~(3<<9); - GPHCON = (GPHCON & ~(0xF<<18)) | 5<<18; + SCL_HI_IN; + SDA_HI_IN; } diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c index 212b8facb2..3c9f77c5f9 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c @@ -4,7 +4,6 @@ #include "mmu-meg-fx.h" #include "lcd.h" -#include enum { @@ -65,9 +64,15 @@ void system_init(void) /* Turn off USB host */ CLKCON &= ~(1 << 6); + + /* Turn off USB device */ + CLKCON &= ~(1 << 7); /* Turn off NAND flash controller */ CLKCON &= ~(1 << 4); + + /* Turn off the USB PLL */ + CLKSLOW |= (1 << 7); } diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c index af66e2a60c..374fb21136 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c @@ -17,7 +17,6 @@ * ****************************************************************************/ #include "config.h" -#include #include "cpu.h" #include "system.h" #include "kernel.h" @@ -46,14 +45,14 @@ void usb_init_device(void) /* Input is the default configuration, only pullups need to be disabled */ /* GPFUP|=0x02; */ - USB_VPLUS_PWR_ASSERT; GPBCON=( GPBCON&~(1<<13) ) | (1 << 12); + USB_VPLUS_PWR_ASSERT; sleep(HZ/20); /* Reset the usb port */ - USB_RST_ASSERT; GPBCON = (GPBCON & ~0x200) | 0x100; /* Make sure reset line is an output */ + USB_RST_ASSERT; sleep(HZ/25); USB_RST_DEASSERT; @@ -75,6 +74,9 @@ void usb_init_device(void) void usb_enable(bool on) { + GPHCON=( GPHCON&~(1<<17) ) | (1<<16); /* Make the pin an output */ + GPHUP|=1<<8; /* Disable pullup in SOC as we are now driving */ + if (on) { USB_VPLUS_PWR_ASSERT; @@ -86,9 +88,5 @@ void usb_enable(bool on) USB_VPLUS_PWR_DEASSERT; } - /* Make sure USB_CRADLE_BUS pin is an output */ - GPHCON=( GPHCON&~(1<<17) ) | (1<<16); /* Make the pin an output */ - GPHUP|=1<<8; /* Disable pullup in SOC as we are now driving */ - sleep(HZ/20); // > 50ms for detecting the enable state change } -- cgit v1.2.3