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
This commit is contained in:
Karl Kurbjun 2007-05-07 19:34:34 +00:00
parent 7cdd0fe6ea
commit 173b611921
14 changed files with 297 additions and 865 deletions

View file

@ -18,7 +18,6 @@
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include <stdbool.h>
#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)

View file

@ -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_control = BUTTONLIGHT_CONTROL_IDLE;
buttonlight_state = BUTTONLIGHT_MODE_OFF;
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;
}
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 */
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;
}
buttonlight_flickering--;
}
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);
}
}
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;
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;
}
}
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;
break;
case BUTTONLIGHT_HELPER_SET_FINAL:
sc606_write(SC606_REG_C, buttonlight_setting-1);
buttonlight_current = buttonlight_setting;
buttonlight_state = buttonlight_saved_state;
break;
default:
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)
{
case BACKLIGHT_CONTROL_IDLE:
backlight_control = BACKLIGHT_CONTROL_IDLE;
}
else
{
backlight_control = BACKLIGHT_CONTROL_OFF;
}
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
if(backlight_target>sc606regAval)
sc606regAval++;
else
sc606regAval--;
break;
default:
break;
}
else
switch (buttonlight_control)
{
time_til_fade = fade_interval;
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
if(buttonlight_target>sc606regBval)
sc606regCval=++sc606regBval;
else
sc606regCval=--sc606regBval;
break;
default:
break;
}
break;
}
if(backlight_current)
switch (sc606_control)
{
case SC606_CONTROL_IDLE:
if(sc606_changed)
sc606_control=SC606_CONTROL_A12;
else
sc606_control=SC606_CONTROL_IDLE;
break;
case SC606_CONTROL_A12:
sc606_write(SC606_REG_A , sc606regAval);
sc606_control=SC606_CONTROL_B12;
break;
case SC606_CONTROL_B12:
sc606_write(SC606_REG_B , sc606regBval);
sc606_control=SC606_CONTROL_C12;
break;
case SC606_CONTROL_C12:
sc606_write(SC606_REG_C , sc606regCval);
sc606_control=SC606_CONTROL_CONF;
break;
case SC606_CONTROL_CONF:
sc606_write(SC606_REG_CONF , sc606regCONFval);
sc606_changed=false;
sc606_control=SC606_CONTROL_IDLE;
break;
default:
sc606_control=SC606_CONTROL_A12;
break;
}
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;
}

View file

@ -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);

View file

@ -17,7 +17,6 @@
*
****************************************************************************/
#include <stdlib.h>
#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);

View file

@ -1,6 +1,5 @@
#include "config.h"
#include "cpu.h"
#include <stdbool.h>
#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_LO_OUT (GPHCON |= (1 << 20));(GPHDAT &= ~(1 << 10));
#define SCL_HI_IN (GPHCON &= ~(3 << 20));while(!SCL);
#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 = 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
*/
/* 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)
#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;
bool 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;
SDA_HI_IN;
DELAY(DELAY_MID);
SCL_HI_IN;
ret = (SDA != 0); /* ack failed if SDA is not low */
DELAY_HI;
ret = !SDA;
SCL_LO;
DELAY_LO;
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;
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;
/* 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);
}
if (SDA)
byte |= i;
SCL_LO;
}
SDA_OUTPUT;
sc606_i2c_ack();
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;
}

View file

@ -4,7 +4,6 @@
#include "mmu-meg-fx.h"
#include "lcd.h"
#include <stdio.h>
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);
}

View file

@ -17,7 +17,6 @@
*
****************************************************************************/
#include "config.h"
#include <stdbool.h>
#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
}