Add MPIO HD200 port - new files

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25725 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Marcin Bukat 2010-04-26 21:40:16 +00:00
parent b09d3aec39
commit 28d54c6016
29 changed files with 3756 additions and 0 deletions

View file

@ -0,0 +1,84 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "system.h"
#include "kernel.h"
#include "thread.h"
#include "adc.h"
volatile unsigned short adc_data[NUM_ADC_CHANNELS] IBSS_ATTR;
/* Reading takes 4096 adclk ticks
* We do read one channel at once
*
* state FCPU Fbus Fadc bus/Fadc Fchannelread
* default 11.2896 MHz 5.6448 MHz 5.6448 MHz 2 172.2656 Hz
* normal 45.1584 MHz 22.5792 MHz 2.8224 MHz 8 172.2656 Hz
* max 124.1856 MHz 62.0928 MHz 1.9404 MHz 32 118.4326 Hz
*/
void ADC(void) __attribute__ ((interrupt_handler,section(".icode")));
void ADC(void)
{
static unsigned char channel;
/* read current value */
adc_data[(channel & 0x03)] = ADVALUE;
/* switch channel
*
* set source remark
* ADCONFIG is 16bit wide so we have to shift data by 16bits left
* thats why we shift <<24 instead of <<8
*/
channel++;
and_l(~(3<<24),&ADCONFIG);
or_l( (((channel & 0x03) << 8 )|(1<<7))<<16, &ADCONFIG);
}
unsigned short adc_scan(int channel)
{
/* maybe we can drop &0x03 part */
return adc_data[(channel&0x03)];
}
void adc_init(void)
{
/* GPIO38 GPIO39 */
and_l(~((1<<6)|(1<<7)), &GPIO1_FUNCTION);
/* ADOUT_SEL = 01
* SOURCE SELECT = 000
* CLEAR INTERRUPT FLAG
* ENABLE INTERRUPT = 1
* ADOUT_DRIVE = 00
* ADCLK_SEL = 011 (busclk/8)
*/
ADCONFIG = (1<<10)|(1<<7)|(1<<6)|(1<<1)|(1<<0);
/* ADC interrupt level 4.0 */
or_l((4<<28), &INTPRI8);
}

View file

@ -0,0 +1,41 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* 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 _ADC_TARGET_H_
#define _ADC_TARGET_H_
#define NUM_ADC_CHANNELS 4
#define ADC_BUTTONS 1
#define ADC_REMOTE 0
#define ADC_BATTERY 2
#define ADC_REMOTEDETECT 3
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
/* Force a scan now */
unsigned short adc_scan(int channel);
static inline unsigned short adc_read(int channel)
{
return adc_scan(channel);
}
#endif /* _ADC_TARGET_H_ */

View file

@ -0,0 +1,86 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "kernel.h"
#include "system.h"
#include "backlight.h"
#include "backlight-target.h"
#include "lcd.h"
static bool _backlight_on = false;
static int _brightness = DEFAULT_BRIGHTNESS_SETTING;
/* Returns the current state of the backlight (true=ON, false=OFF). */
bool _backlight_init(void)
{
and_l(~(1<<28),&GPIO_OUT);
or_l((1<<28),&GPIO_FUNCTION);
or_l((1<<28),&GPIO_ENABLE);
return true;
}
void _backlight_hw_on(void)
{
if (_backlight_on)
return;
_backlight_set_brightness(_brightness);
_backlight_on = true;
}
void _backlight_hw_off(void)
{
/* GPIO28 low */
and_l(~(1<<28),&GPIO_OUT);
_backlight_on = false;
}
void _backlight_set_brightness(int val)
{
unsigned char i;
and_l(~(1<<28),&GPIO_OUT);
sleep(4);
for (i=0;i<val;i++)
{
or_l((1<<28),&GPIO_OUT);
and_l(~(1<<28),&GPIO_OUT);
}
or_l((1<<28),&GPIO_OUT);
_brightness = val;
}
void _remote_backlight_on(void)
{
/* I don't have remote to play with */
}
void _remote_backlight_off(void)
{
/* I don't have remote to play with */
}

View file

@ -0,0 +1,35 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef BACKLIGHT_TARGET_H
#define BACKLIGHT_TARGET_H
bool _backlight_init(void); /* Returns backlight current state (true=ON). */
void _backlight_hw_on(void);
void _backlight_hw_off(void);
void _backlight_set_brightness(int val);
#define _backlight_on() _backlight_hw_on()
#define _backlight_off() _backlight_hw_off()
#define _backlight_on_isr() _backlight_hw_on()
#define _backlight_off_isr() _backlight_hw_off()
#define _backlight_on_normal() _backlight_hw_on()
#define _backlight_off_normal() _backlight_hw_off()
#endif

View file

@ -0,0 +1,123 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "system.h"
#include "button.h"
#include "backlight.h"
#include "adc.h"
void button_init_device(void)
{
/* Set GPIO36, GPIO56 as general purpose inputs */
or_l((1<<4)|(1<<24),&GPIO1_FUNCTION);
and_l(~((1<<4)|(1<<24)),&GPIO1_ENABLE);
}
bool button_hold(void)
{
/* GPIO36 active high */
return (GPIO1_READ & (1<<4))?true:false;
}
/*
* Get button pressed from hardware
*/
int button_read_device(void)
{
int btn = BUTTON_NONE;
int data = 0;
static bool hold_button = false;
/* for moving average filter */
static unsigned short button_filter[4];
static unsigned char index;
bool hold_button_old;
/* normal buttons */
hold_button_old = hold_button;
hold_button = button_hold();
#ifndef BOOTLOADER
if (hold_button != hold_button_old)
backlight_hold_changed(hold_button);
#endif
if (!hold_button)
{
/* simple moving average filter with 4 item window */
button_filter[index&0x03] = adc_scan(ADC_BUTTONS);
index++;
data = (button_filter[0]+button_filter[1] \
+button_filter[2]+button_filter[3])>>2;
if (data < 2250) // valid button
{
if (data < 900) /* middle */
{
if (data < 500)
{
if (data > 200)
/* 200 - 500 */
btn = BUTTON_REC;
}
else /* 900 - 500 */
btn = BUTTON_VOL_DOWN;
}
else /* 2250 - 900 */
{
if (data < 1600)
{
/* 1600 - 900 */
if (data < 1200)
/* 1200 - 900 */
btn = BUTTON_VOL_UP;
else /* 1600 - 1200 */
btn = BUTTON_NEXT;
}
else /* 1600 - 2250 */
{
if (data < 1900)
/* 1900 - 1600 */
btn = BUTTON_PREV;
else /* 1900 - 2250 */
btn = BUTTON_SELECT;
}
}
}
}
data = GPIO1_READ;
/* GPIO56 active high main PLAY/PAUSE/ON */
if (!hold_button && ((data & (1<<24))))
btn |= BUTTON_PLAY;
return btn;
}

View file

@ -0,0 +1,103 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#define LCD_BASE_ADDRESS 0xf0000000
.section .icode,"ax",@progbits
.align 2
.global lcd_write_command
.type lcd_write_command,@function
lcd_write_command:
move.l (4, %sp), %d0
move.w %d0, LCD_BASE_ADDRESS /* data is 1byte but CF uses word
* transfers only */
rts
.wc_end:
.size lcd_write_command,.wc_end-lcd_write_command
.align 2
.global lcd_write_command_e
.type lcd_write_command_e,@function
lcd_write_command_e:
lea.l LCD_BASE_ADDRESS, %a0
move.l (4, %sp), %d0 /* Command */
move.w %d0, (%a0)
move.l (8, %sp), %d0 /* Data */
move.w %d0, (%a0) /* Write to LCD */
rts
.wce_end:
.size lcd_write_command_e,.wce_end-lcd_write_command_e
.align 2
.global lcd_write_data
.type lcd_write_data,@function
/* PIXELFORMAT = VERTICAL_INTERLEAVED
* this means that data is packed verticaly in 8 pixels columns
* first byte is lsb of 2bit color in column
* second byte is msb of 2bit color in column
* so one word of data equals 8 pixels i 2bits color depth packed
* verticaly
*/
lcd_write_data:
movem.l (4, %sp), %a0 /* Data pointer */
move.l (8, %sp), %d0 /* Length i in words */
lea LCD_BASE_ADDRESS+2, %a1 /* LCD data port address */
btst #0, %d0 /* longwords multiply? */
beq .l_write
.w_write:
move.w (%a0)+, %d1 /* load data 3 cycles*/
move.w %d1, (%a1) /* first byte 1 cycle*/
lsr.l #8, %d1 /* load second byte 1 cycle*/
move.w %d1, (%a1) /* transfer 1 cycle*/
subq.l #1, %d0 /* decrement counter 1 cycle*/
beq .write_end
.l_write:
move.l (%a0)+, %d1 /* load data 2 cycles*/
swap %d1 /* 1 cycle */
move.w %d1, (%a1) /* first byte 1 cycle*/
lsr.l #8, %d1 /* 1 cycle */
move.w %d1, (%a1) /* second byte 1 cycle*/
lsr.l #8, %d1 /* 1 cycle */
move.w %d1, (%a1) /* third byte 1 cycle*/
lsr.l #8, %d1 /* 1 cycle */
move.w %d1, (%a1) /* forth byte 1 cycle*/
subq.l #2, %d0 /* decrement counter 1 cycle*/
bne .l_write
.write_end:
rts
.size lcd_write_data,.wd_end-lcd_write_data

View file

@ -0,0 +1,241 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "system.h"
#include "kernel.h"
#include "lcd.h"
/*** definitions ***/
/* TOMATO LSI 0350 - definitions and slightly tweaked functions
* taken from lcd-remote-iaudio.c
*/
#define LCD_SET_DUTY_RATIO 0x48
#define LCD_SELECT_ADC 0xa0
#define LCD_SELECT_SHL 0xc0
#define LCD_SET_COM0 0x44
#define LCD_OSC_ON 0xab
#define LCD_SELECT_DCDC 0x64
#define LCD_SELECT_RES 0x20
#define LCD_SET_VOLUME 0x81
#define LCD_SET_BIAS 0x50
#define LCD_CONTROL_POWER 0x28
#define LCD_DISPLAY_ON 0xae
#define LCD_SET_INITLINE 0x40
#define LCD_SET_COLUMN 0x10
#define LCD_SET_PAGE 0xb0
#define LCD_SET_GRAY 0x88
#define LCD_SET_PWM_FRC 0x90
#define LCD_SET_POWER_SAVE 0xa8
#define LCD_REVERSE 0xa6
#define LCD_RESET 0xe2
/* cached settings */
static bool cached_invert = false;
static bool cached_flip = false;
static int cached_contrast = DEFAULT_CONTRAST_SETTING;
bool lcd_initialized = false;
/*** hardware configuration ***/
int lcd_default_contrast(void)
{
return DEFAULT_CONTRAST_SETTING;
}
void lcd_powersave(bool on)
{
/* What is the point of having else construct here? */
if(lcd_initialized) {
if (on)
lcd_write_command(LCD_SET_POWER_SAVE | 1);
else
lcd_write_command(LCD_SET_POWER_SAVE | 1);
}
}
void lcd_set_contrast(int val)
{
if (val < MIN_CONTRAST_SETTING)
val = MIN_CONTRAST_SETTING;
else if (val > MAX_CONTRAST_SETTING)
val = MAX_CONTRAST_SETTING;
cached_contrast = val;
if(lcd_initialized)
lcd_write_command_e(LCD_SET_VOLUME, val);
}
void lcd_set_invert_display(bool yesno)
{
cached_invert = yesno;
if(lcd_initialized)
lcd_write_command(LCD_REVERSE | yesno);
}
/* turn the display upside down (call lcd_update() afterwards) */
void lcd_set_flip(bool yesno)
{
cached_flip = yesno;
if(lcd_initialized)
{
if(yesno)
{
lcd_write_command(LCD_SELECT_ADC | 1);
lcd_write_command(LCD_SELECT_SHL | 0);
lcd_write_command_e(LCD_SET_COM0, 0);
}
else
{
lcd_write_command(LCD_SELECT_ADC | 0);
lcd_write_command(LCD_SELECT_SHL | 8);
lcd_write_command_e(LCD_SET_COM0, 0);
}
}
}
void lcd_shutdown(void)
{
/* Set power save -> Power OFF (VDD - VSS) .. that's it */
if (lcd_initialized)
lcd_write_command(LCD_SET_POWER_SAVE | 1);
}
void lcd_init_device(void)
{
and_l(~0x00000800, &GPIO_FUNCTION); /* CS3 line */
/* LCD Reset GPO34 */
or_l(0x00000004, &GPIO1_ENABLE); /* set as output */
or_l(0x00000004, &GPIO1_FUNCTION); /* switch to secondary function - GPIO */
and_l(~0x00000004, &GPIO1_OUT); /* RESET low */
sleep(1); /* delay at least 1000 ns */
or_l(0x00000004, &GPIO1_OUT); /* RESET high */
sleep(1);
/* parameters setup taken from original firmware */
lcd_write_command(LCD_RESET);
lcd_write_command_e(LCD_SET_DUTY_RATIO,0x80); /* 1/128 */
lcd_write_command(LCD_OSC_ON);
lcd_write_command(LCD_SELECT_DCDC | 3); /* DC/DC 6xboost */
lcd_write_command(LCD_SELECT_RES | 7); /* Regulator resistor: 7.2 */
lcd_write_command(LCD_SET_BIAS | 6); /* 1/11 */
lcd_write_command(LCD_SET_PWM_FRC | 6); /* 3FRC + 12PWM */
lcd_write_command_e(LCD_SET_GRAY | 0, 0x00);
lcd_write_command_e(LCD_SET_GRAY | 1, 0x00);
lcd_write_command_e(LCD_SET_GRAY | 2, 0x0c);
lcd_write_command_e(LCD_SET_GRAY | 3, 0x00);
lcd_write_command_e(LCD_SET_GRAY | 4, 0xc4);
lcd_write_command_e(LCD_SET_GRAY | 5, 0x00);
lcd_write_command_e(LCD_SET_GRAY | 6, 0xcc);
lcd_write_command_e(LCD_SET_GRAY | 7, 0x00);
lcd_write_command(LCD_CONTROL_POWER | 7); /* All circuits ON */
lcd_write_command(LCD_DISPLAY_ON | 1); /* display on */
/* Ok we are ready */
lcd_initialized = true;
lcd_set_flip(cached_flip);
lcd_set_contrast(cached_contrast);
lcd_set_invert_display(cached_invert);
lcd_update();
}
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void) ICODE_ATTR;
void lcd_update(void)
{
int y;
if(!lcd_initialized)
return;
for(y = 0;y < LCD_FBHEIGHT;y++)
{
lcd_write_command(LCD_SET_PAGE | y);
lcd_write_command_e(LCD_SET_COLUMN, 0);
lcd_write_data(lcd_framebuffer[y], LCD_WIDTH);
}
}
/* Update a fraction of the display. */
void lcd_update_rect(int, int, int, int) ICODE_ATTR;
void lcd_update_rect(int x, int y, int width, int height)
{
int ymax;
if (!lcd_initialized)
return;
/* The Y coordinates have to work on even 8 pixel rows */
ymax = (y + height-1) >> 3;
y >>= 3;
if(x + width > LCD_WIDTH)
width = LCD_WIDTH - x;
if (width <= 0)
return; /* nothing left to do, 0 is harmful to lcd_write_data() */
if(ymax >= LCD_FBHEIGHT)
ymax = LCD_FBHEIGHT-1;
/* Copy specified rectange bitmap to hardware */
for (; y <= ymax; y++)
{
lcd_write_command(LCD_SET_PAGE | y );
lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0x0f);
lcd_write_data (&lcd_framebuffer[y][x], width);
}
}
void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
int x, int by, int width, int bheight, int stride)
{
(void)values;
(void)phases;
(void)x;
(void)by;
(void)width;
(void)bheight;
(void)stride;
/* empty stub */
}
void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
int bheight, int stride)
{
(void)data;
(void)x;
(void)by;
(void)width;
(void)bheight;
(void)stride;
/* empty stub */
}

View file

@ -0,0 +1,113 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include <stdbool.h>
#include "kernel.h"
#include "system.h"
#include "lcd.h"
#include "power.h"
#if CONFIG_TUNER
bool tuner_power(bool status)
{
(void)status;
if (status)
{
and_l(~(1<<17), &GPIO1_OUT);
}
else
{
or_l((1<<17), &GPIO1_OUT);
}
return status;
}
#endif /* #if CONFIG_TUNER */
void power_init(void)
{
/* GPIO53 has to be high - low resets device */
/* GPIO49 is FM related */
or_l((1<<21)|(1<<17), &GPIO1_OUT);
or_l((1<<21)|(1<<17), &GPIO1_ENABLE);
or_l((1<<21)|(1<<17)|(1<<14), &GPIO1_FUNCTION);
and_l(~(1<<15), &GPIO_OUT);
or_l((1<<15),&GPIO_ENABLE);
or_l((1<<15),&GPIO_FUNCTION);
or_l((1<<23), &GPIO_OUT);
and_l(~(1<<23), &GPIO_ENABLE);
or_l((1<<23), &GPIO_FUNCTION);
#ifndef BOOTLOADER
/* The boot loader controls the power */
ide_power_enable(true);
#endif
}
unsigned int power_input_status(void)
{
unsigned int status = POWER_INPUT_NONE;
/* GPIO46 is AC plug detect (low = AC plugged) */
if (!(GPIO1_READ & (1<<14)))
status |= POWER_INPUT_MAIN_CHARGER;
return status;
}
/* Returns true if the unit is charging the batteries. */
bool charging_state(void)
{
if (!(GPIO1_READ & (1<<14)))
return (GPIO_READ & (1<<30) )?false:true;
else
return false;
}
void ide_power_enable(bool on)
{
(void)on;
if (on)
and_l(~(1<<31),&GPIO_OUT);
else
or_l((1<<31),&GPIO_OUT);
or_l((1<<31),&GPIO_ENABLE);
or_l((1<<31),&GPIO_FUNCTION);
}
bool ide_powered(void)
{
return true;
}
void power_off(void)
{
lcd_shutdown();
set_irq_level(DISABLE_INTERRUPTS);
and_l(~(1<<21), &GPIO1_OUT); /* pull KEEPACT low */
asm("halt");
while(1);
}

View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "adc.h"
#include "powermgmt.h"
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
3700
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
3650
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
/* from OF and measurements voltage range is 3.7-4.1 V */
{ 3700, 3740, 3780, 3820, 3860, 3900, 3940, 3980, 4020, 4060, 4100 }
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short percent_to_volt_charge[11] =
{
/* values measured over one full charging cycle */
3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230 /* LiPo */
};
/* 3.33V as reference */
#define BATTERY_SCALE_FACTOR 3330
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 11;
}

View file

@ -0,0 +1,125 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "kernel.h"
#include "system.h"
#include "power.h"
#include "timer.h"
/* Settings for all possible clock frequencies (with properly working timers)
*
* xxx_REFRESH_TIMER below
* system.h, CPUFREQ_xxx_MULT |
* | |
* V V
* PLLCR & Rftim. IDECONFIG1/IDECONFIG2
* CPUCLK/Hz MULT ~0x70c00000 16MB CSCR0 CSCR1 CS2Pre CS2Post CS2Wait
* -------------------------------------------------------------------------
* 11289600 1 0x00000200 4 0x0180 0x0180 1 1 0
* 22579200 2 0x05028049 10 0x0180 0x0180 1 1 0
* 33868800 3 0x03024049 15 0x0180 0x0180 1 1 0
* 45158400 4 0x05028045 21 0x0180 0x0180 1 1 0
* 56448000 5 0x02028049 26 0x0580 0x0580 2 1 0
* 67737600 6 0x03024045 32 0x0580 0x0980 2 1 0
* 79027200 7 0x0302a045 37 0x0580 0x0d80 2 1 0
* 90316800 8 0x03030045 43 0x0980 0x0d80 2 1 0
* 101606400 9 0x01024049 48 0x0980 0x1180 2 1 0
* 112896000 10 0x01028049 54 0x0980 0x1580 3 1 0
* 124185600 11 0x0102c049 59 0x0980 0x1180 3 1 1
*/
#define MAX_REFRESH_TIMER 59
#define NORMAL_REFRESH_TIMER 21
#define DEFAULT_REFRESH_TIMER 4
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency (long) __attribute__ ((section (".icode")));
void set_cpu_frequency(long frequency)
#else
void cf_set_cpu_frequency (long) __attribute__ ((section (".icode")));
void cf_set_cpu_frequency(long frequency)
#endif
{
switch(frequency)
{
case CPUFREQ_MAX:
DCR = (0x8200 | DEFAULT_REFRESH_TIMER);
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
PLLCR = 0x0102c049 | (PLLCR & 0x70C00000);
CSCR0 = 0x00001180; /* Flash: 4 wait states */
CSCR3 = 0x00001180; /* LCD: 4 wait states */
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_MAX;
IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(3<<10);
/* BUFEN2 enable on /CS2 | CS2Post 1 clock| CS2Pre 3 clocks*/
IDECONFIG2 = (1<<18)|(1<<16)|(1<<8)|(1<<0); /* TA /CS2 enable + CS2wait */
and_l(~(0x07<<16), &ADCONFIG);
or_l(((1<<7)|(1<<2)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/32 */
break;
case CPUFREQ_NORMAL:
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
PLLCR = 0x05028045 | (PLLCR & 0x70C00000);
CSCR0 = 0x00000580; /* Flash: 1 wait state */
CSCR3 = 0x00000980; /* LCD: 0 wait states */
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_NORMAL;
IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(1<<10);
IDECONFIG2 = (1<<18)|(1<<16);
and_l(~(0x07<<16), &ADCONFIG);
or_l(((1<<7)|(1<<1)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/8 */
break;
default:
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true);
/* Power down PLL, but keep CLSEL and CRSEL */
PLLCR = 0x00000200 | (PLLCR & 0x70C00000);
CSCR0 = 0x00000180; /* Flash: 0 wait states */
CSCR3 = 0x00000980; /* LCD: 0 wait states */
DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_DEFAULT;
IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(1<<10);
IDECONFIG2 = (1<<18)|(1<<16);
and_l(~(0x07<<16), &ADCONFIG);
or_l(((1<<7)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/2 */
break;
}
}

View file

@ -0,0 +1,81 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:$
*
* Copyright (C) 2010 Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include <stdbool.h>
#include "cpu.h"
#include "system.h"
#include "kernel.h"
#include "usb.h"
void usb_init_device(void)
{
/* GPIO42 is USB detect input
* but it also serves as MCLK2 for DAC
*/
and_l(~(1<<4), &GPIO1_OUT);
or_l((1<<4)|(1<<18), &GPIO1_ENABLE); /* GPIO36 GPIO50 */
or_l((1<<4)|(1<<18), &GPIO1_FUNCTION);
/* GPIO22 GPIO30*/
/* GPIO31 has to be low to ATA work */
or_l((1<<22)|(1<<30), &GPIO_OUT);
or_l((1<<22)|(1<<30)|(1<<31), &GPIO_ENABLE);
or_l((1<<22)|(1<<30)|(1<<31), &GPIO_FUNCTION);
}
int usb_detect(void)
{
/* GPIO42 active low*/
return (GPIO1_READ & (1<<10)) ? USB_EXTRACTED : USB_INSERTED;
}
void usb_enable(bool on)
{
if(on)
{
or_l((1<<18),&GPIO1_OUT); /* GPIO50 high */
and_l(~(1<<30),&GPIO_OUT); /* GPIO30 low */
/* GPIO36 low delay GPIO36 high delay */
and_l(~(1<<4),&GPIO1_OUT);
or_l((1<<4),&GPIO1_OUT);
and_l(~(1<<18),&GPIO1_OUT); /* GPIO50 low */
sleep(HZ/5); /* delay 200 ms */
and_l(~(1<<22),&GPIO_OUT); /* GPIO22 low */
}
else
{
/* GPIO36 low delay GPIO36 high delay */
and_l(~(1<<4),&GPIO1_OUT);
sleep(HZ/100);
or_l((1<<4),&GPIO1_OUT);
sleep(HZ/100);
or_l((1<<22),&GPIO_OUT); /* GPIO22 high */
or_l((1<<30),&GPIO_OUT); /* GPIO30 high */
and_l(~(1<<4),&GPIO1_OUT); /* GPIO36 low */
//or_l((1<<18),&GPIO1_OUT); /* GPIO50 high */
}
}