diff options
author | Rob Purchase <shotofadds@rockbox.org> | 2008-01-14 22:04:48 +0000 |
---|---|---|
committer | Rob Purchase <shotofadds@rockbox.org> | 2008-01-14 22:04:48 +0000 |
commit | 47ea030e2e68a51f91a2c2302b7ea4d3ee1a2a07 (patch) | |
tree | 0a48ce653e22ec9a2673474f718217d9659e0c6b /firmware/target/arm/tcc780x | |
parent | b30ca8ca5ab6c8ea27b8fe1f5fb38ebad09b7e62 (diff) | |
download | rockbox-47ea030e2e68a51f91a2c2302b7ea4d3ee1a2a07.tar.gz rockbox-47ea030e2e68a51f91a2c2302b7ea4d3ee1a2a07.zip |
Initial Cowon D2 commit:
* bootloader test program (basic LCD & button drivers, reads touchscreen)
* work-in-progress stubs for main build
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16090 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/tcc780x')
20 files changed, 1910 insertions, 0 deletions
diff --git a/firmware/target/arm/tcc780x/adc-tcc780x.c b/firmware/target/arm/tcc780x/adc-tcc780x.c new file mode 100644 index 0000000000..871db2b61d --- /dev/null +++ b/firmware/target/arm/tcc780x/adc-tcc780x.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "system.h" | ||
22 | #include "kernel.h" | ||
23 | #include "thread.h" | ||
24 | #include "string.h" | ||
25 | #include "adc.h" | ||
26 | |||
27 | /* | ||
28 | TODO: We probably want to do this on the timer interrupt once we get | ||
29 | interrupts going - see the sh-adc.c implementation for an example which | ||
30 | looks like it should work well with the TCC77x. | ||
31 | |||
32 | Also, this code is practically identical between 77x & 780x targets. | ||
33 | Should probably find a common location to avoid the duplication. | ||
34 | */ | ||
35 | |||
36 | static unsigned short adcdata[8]; | ||
37 | |||
38 | static void adc_do_read(void) | ||
39 | { | ||
40 | int i; | ||
41 | uint32_t adc_status; | ||
42 | |||
43 | PCLK_ADC |= PCK_EN; /* Enable ADC clock */ | ||
44 | |||
45 | /* Start converting the first 4 channels */ | ||
46 | for (i = 0; i < 4; i++) | ||
47 | ADCCON = i; | ||
48 | |||
49 | /* Wait for data to become stable */ | ||
50 | while ((ADCDATA & 0x1) == 0); | ||
51 | |||
52 | /* Now read the values back */ | ||
53 | for (i=0;i < 4; i++) { | ||
54 | adc_status = ADCSTATUS; | ||
55 | adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff; | ||
56 | } | ||
57 | |||
58 | PCLK_ADC &= ~PCK_EN; /* Disable ADC clock */ | ||
59 | } | ||
60 | |||
61 | unsigned short adc_read(int channel) | ||
62 | { | ||
63 | /* Either move this to an interrupt routine, or only perform the read if | ||
64 | the last call was X length of time ago. */ | ||
65 | adc_do_read(); | ||
66 | |||
67 | return adcdata[channel]; | ||
68 | } | ||
69 | |||
70 | void adc_init(void) | ||
71 | { | ||
72 | /* consider configuring PCK_ADC source here */ | ||
73 | |||
74 | ADCCON = (1<<4); /* Leave standby mode */ | ||
75 | ADCCFG |= 0x00000003; /* Single-mode, auto power-down */ | ||
76 | } | ||
diff --git a/firmware/target/arm/tcc780x/ata-nand-tcc780x.c b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c new file mode 100644 index 0000000000..5aed090d5c --- /dev/null +++ b/firmware/target/arm/tcc780x/ata-nand-tcc780x.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "ata.h" | ||
20 | #include "ata-target.h" | ||
21 | #include "ata_idle_notify.h" | ||
22 | #include "system.h" | ||
23 | #include <string.h> | ||
24 | #include "thread.h" | ||
25 | #include "led.h" | ||
26 | #include "disk.h" | ||
27 | #include "panic.h" | ||
28 | #include "usb.h" | ||
29 | |||
30 | /* for compatibility */ | ||
31 | int ata_spinup_time = 0; | ||
32 | |||
33 | long last_disk_activity = -1; | ||
34 | |||
35 | /** static, private data **/ | ||
36 | static bool initialized = false; | ||
37 | |||
38 | static long next_yield = 0; | ||
39 | #define MIN_YIELD_PERIOD 2000 | ||
40 | |||
41 | /* API Functions */ | ||
42 | |||
43 | void ata_led(bool onoff) | ||
44 | { | ||
45 | led(onoff); | ||
46 | } | ||
47 | |||
48 | int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, | ||
49 | void* inbuf) | ||
50 | { | ||
51 | #warning function not implemented | ||
52 | (void)start; | ||
53 | (void)incount; | ||
54 | (void)inbuf; | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, | ||
59 | const void* outbuf) | ||
60 | { | ||
61 | #warning function not implemented | ||
62 | (void)start; | ||
63 | (void)count; | ||
64 | (void)outbuf; | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | void ata_spindown(int seconds) | ||
69 | { | ||
70 | #warning function not implemented | ||
71 | (void)seconds; | ||
72 | } | ||
73 | |||
74 | bool ata_disk_is_active(void) | ||
75 | { | ||
76 | #warning function not implemented | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | void ata_sleep(void) | ||
81 | { | ||
82 | #warning function not implemented | ||
83 | } | ||
84 | |||
85 | void ata_spin(void) | ||
86 | { | ||
87 | #warning function not implemented | ||
88 | } | ||
89 | |||
90 | /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */ | ||
91 | int ata_hard_reset(void) | ||
92 | { | ||
93 | #warning function not implemented | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int ata_soft_reset(void) | ||
98 | { | ||
99 | #warning function not implemented | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | void ata_enable(bool on) | ||
104 | { | ||
105 | #warning function not implemented | ||
106 | (void)on; | ||
107 | } | ||
108 | |||
109 | int ata_init(void) | ||
110 | { | ||
111 | #warning function not implemented | ||
112 | return 0; | ||
113 | } | ||
diff --git a/firmware/target/arm/tcc780x/ata-target.h b/firmware/target/arm/tcc780x/ata-target.h new file mode 100644 index 0000000000..79ac638de1 --- /dev/null +++ b/firmware/target/arm/tcc780x/ata-target.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef ATA_TARGET_H | ||
20 | #define ATA_TARGET_H | ||
21 | |||
22 | #endif | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/adc-target.h b/firmware/target/arm/tcc780x/cowond2/adc-target.h new file mode 100644 index 0000000000..873183d721 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/adc-target.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _ADC_TARGET_H_ | ||
20 | #define _ADC_TARGET_H_ | ||
21 | |||
22 | #define NUM_ADC_CHANNELS 4 | ||
23 | |||
24 | #define ADC_BUTTONS 0 | ||
25 | |||
26 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/backlight-target.h b/firmware/target/arm/tcc780x/cowond2/backlight-target.h new file mode 100644 index 0000000000..0563fc20f5 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/backlight-target.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef BACKLIGHT_TARGET_H | ||
20 | #define BACKLIGHT_TARGET_H | ||
21 | |||
22 | #include "tcc780x.h" | ||
23 | |||
24 | #define _backlight_init() true | ||
25 | |||
26 | /* nb: we can set the backlight intensity using PCF50606 register 0x35 */ | ||
27 | |||
28 | static inline void _backlight_on(void) | ||
29 | { | ||
30 | /* Enable backlight */ | ||
31 | GPIOA_SET = (1<<6); | ||
32 | } | ||
33 | |||
34 | static inline void _backlight_off(void) | ||
35 | { | ||
36 | /* Disable backlight */ | ||
37 | GPIOA_CLEAR = (1<<6); | ||
38 | } | ||
39 | |||
40 | #endif | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/button-cowond2.c b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c new file mode 100644 index 0000000000..dccdf4e8e0 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/button-cowond2.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | #include "button.h" | ||
23 | #include "adc.h" | ||
24 | |||
25 | void button_init_device(void) | ||
26 | { | ||
27 | /* Nothing to do */ | ||
28 | } | ||
29 | |||
30 | int button_read_device(void) | ||
31 | { | ||
32 | int btn = BUTTON_NONE; | ||
33 | int adc; | ||
34 | |||
35 | if (GPIOB & 0x4) | ||
36 | { | ||
37 | adc = adc_read(ADC_BUTTONS); | ||
38 | |||
39 | /* The following contains some abitrary, but working, guesswork */ | ||
40 | if (adc < 0x038) { | ||
41 | btn |= (BUTTON_MINUS | BUTTON_PLUS | BUTTON_MENU); | ||
42 | } else if (adc < 0x048) { | ||
43 | btn |= (BUTTON_MINUS | BUTTON_PLUS); | ||
44 | } else if (adc < 0x058) { | ||
45 | btn |= (BUTTON_PLUS | BUTTON_MENU); | ||
46 | } else if (adc < 0x070) { | ||
47 | btn |= BUTTON_PLUS; | ||
48 | } else if (adc < 0x090) { | ||
49 | btn |= (BUTTON_MINUS | BUTTON_MENU); | ||
50 | } else if (adc < 0x150) { | ||
51 | btn |= BUTTON_MINUS; | ||
52 | } else if (adc < 0x200) { | ||
53 | btn |= BUTTON_MENU; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | /* TODO: Read 'fake' buttons based on touchscreen quadrants. | ||
58 | Question: How can I read from the PCF chip (I2C) in a tick task? */ | ||
59 | |||
60 | if (!(GPIOA & 0x8)) | ||
61 | btn |= BUTTON_HOLD; | ||
62 | |||
63 | if (!(GPIOA & 0x4)) | ||
64 | btn |= BUTTON_POWER; | ||
65 | |||
66 | return btn; | ||
67 | } | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/button-target.h b/firmware/target/arm/tcc780x/cowond2/button-target.h new file mode 100644 index 0000000000..aa336f2f1f --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/button-target.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _BUTTON_TARGET_H_ | ||
21 | #define _BUTTON_TARGET_H_ | ||
22 | |||
23 | #include <stdbool.h> | ||
24 | #include "config.h" | ||
25 | |||
26 | void button_init_device(void); | ||
27 | int button_read_device(void); | ||
28 | |||
29 | /* Main unit's buttons */ | ||
30 | #define BUTTON_POWER 0x00000001 | ||
31 | #define BUTTON_HOLD 0x00000002 | ||
32 | #define BUTTON_PLUS 0x00000004 | ||
33 | #define BUTTON_MINUS 0x00000008 | ||
34 | #define BUTTON_MENU 0x00000010 | ||
35 | |||
36 | /* Faked buttons based on touchscreen quadrants (not yet read) */ | ||
37 | #define BUTTON_UP 0x00000020 | ||
38 | #define BUTTON_DOWN 0x00000040 | ||
39 | #define BUTTON_LEFT 0x00000080 | ||
40 | #define BUTTON_RIGHT 0x00000100 | ||
41 | #define BUTTON_SELECT 0x00000200 | ||
42 | |||
43 | #define BUTTON_MAIN 0x3FF | ||
44 | |||
45 | /* No remote */ | ||
46 | #define BUTTON_REMOTE 0 | ||
47 | |||
48 | /* Software power-off */ | ||
49 | #define POWEROFF_BUTTON BUTTON_POWER | ||
50 | #define POWEROFF_COUNT 40 | ||
51 | |||
52 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/i2c-target.h b/firmware/target/arm/tcc780x/cowond2/i2c-target.h new file mode 100644 index 0000000000..8925a9bae3 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/i2c-target.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef I2C_TARGET_H | ||
20 | #define I2C_TARGET_H | ||
21 | |||
22 | /* Definitions for the D2 I2C bus */ | ||
23 | |||
24 | #define SCL_BIT (1<<0) | ||
25 | #define SDA_BIT (1<<1) | ||
26 | |||
27 | #define SCL (GPIOA & SCL_BIT) | ||
28 | #define SCL_HI GPIOA_SET = SCL_BIT | ||
29 | #define SCL_LO GPIOA_CLEAR = SCL_BIT | ||
30 | |||
31 | #define SDA (GPIOA & SDA_BIT) | ||
32 | #define SDA_HI GPIOA_SET = SDA_BIT | ||
33 | #define SDA_LO GPIOA_CLEAR = SDA_BIT | ||
34 | #define SDA_INPUT GPIOA_DIR &= ~SDA_BIT | ||
35 | #define SDA_OUTPUT GPIOA_DIR |= SDA_BIT | ||
36 | |||
37 | #endif /* I2C_TARGET_H */ | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c new file mode 100644 index 0000000000..181c58669e --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | |||
21 | #include "hwcompat.h" | ||
22 | #include "kernel.h" | ||
23 | #include "lcd.h" | ||
24 | #include "system.h" | ||
25 | #include "cpu.h" | ||
26 | #include "i2c.h" | ||
27 | |||
28 | /* GPIO A pins for LCD panel SDI interface */ | ||
29 | |||
30 | #define LTV250QV_CS (1<<24) | ||
31 | #define LTV250QV_SCL (1<<25) | ||
32 | #define LTV250QV_SDI (1<<26) | ||
33 | |||
34 | /* LCD Controller registers */ | ||
35 | |||
36 | #define LCDC_CTRL (*(volatile unsigned long *)0xF0000000) | ||
37 | #define LCDC_CLKDIV (*(volatile unsigned long *)0xF0000008) | ||
38 | #define LCDC_HTIME1 (*(volatile unsigned long *)0xF000000C) | ||
39 | #define LCDC_HTIME2 (*(volatile unsigned long *)0xF0000010) | ||
40 | #define LCDC_VTIME1 (*(volatile unsigned long *)0xF0000014) | ||
41 | #define LCDC_VTIME2 (*(volatile unsigned long *)0xF0000018) | ||
42 | #define LCDC_VTIME3 (*(volatile unsigned long *)0xF000001C) | ||
43 | #define LCDC_VTIME4 (*(volatile unsigned long *)0xF0000020) | ||
44 | #define LCDC_DS (*(volatile unsigned long *)0xF000005C) | ||
45 | #define LCDC_I1CTRL (*(volatile unsigned long *)0xF000008C) | ||
46 | #define LCDC_I1POS (*(volatile unsigned long *)0xF0000090) | ||
47 | #define LCDC_I1SIZE (*(volatile unsigned long *)0xF0000094) | ||
48 | #define LCDC_I1BASE (*(volatile unsigned long *)0xF0000098) | ||
49 | #define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8) | ||
50 | #define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC) | ||
51 | |||
52 | /* Power and display status */ | ||
53 | static bool display_on = false; /* Is the display turned on? */ | ||
54 | |||
55 | |||
56 | int lcd_default_contrast(void) | ||
57 | { | ||
58 | return 0x1f; | ||
59 | } | ||
60 | |||
61 | void lcd_set_contrast(int val) | ||
62 | { | ||
63 | /* iirc there is an ltv250qv command to do this */ | ||
64 | #warning function not implemented | ||
65 | (void)val; | ||
66 | } | ||
67 | |||
68 | |||
69 | /* LTV250QV panel functions */ | ||
70 | |||
71 | static void ltv250qv_write(unsigned int command) | ||
72 | { | ||
73 | int i; | ||
74 | |||
75 | GPIOA_CLEAR = LTV250QV_CS; | ||
76 | |||
77 | for (i = 23; i >= 0; i--) | ||
78 | { | ||
79 | GPIOA_CLEAR = LTV250QV_SCL; | ||
80 | |||
81 | if ((command>>i) & 1) | ||
82 | GPIOA_SET = LTV250QV_SDI; | ||
83 | else | ||
84 | GPIOA_CLEAR = LTV250QV_SDI; | ||
85 | |||
86 | GPIOA_SET = LTV250QV_SCL; | ||
87 | } | ||
88 | |||
89 | GPIOA_SET = LTV250QV_CS; | ||
90 | } | ||
91 | |||
92 | static void lcd_write_reg(unsigned char reg, unsigned short val) | ||
93 | { | ||
94 | ltv250qv_write(0x740000 | reg); | ||
95 | ltv250qv_write(0x760000 | val); | ||
96 | } | ||
97 | |||
98 | |||
99 | /* TODO: The existing pcf50606 drivers are target-specific, so the following | ||
100 | lonely function exists until a D2 driver exists. */ | ||
101 | |||
102 | void pcf50606_write_reg(unsigned char reg, unsigned char val) | ||
103 | { | ||
104 | unsigned char data[] = { reg, val }; | ||
105 | i2c_write(0x10, data, 2); | ||
106 | } | ||
107 | |||
108 | |||
109 | /* | ||
110 | TEMP: Rough millisecond delay routine used by the LCD panel init sequence. | ||
111 | PCK_TCT must first have been initialised to 2Mhz by calling clock_init(). | ||
112 | */ | ||
113 | static void sleep_ms(unsigned int ms) | ||
114 | { | ||
115 | /* disable timer */ | ||
116 | TCFG1 = 0; | ||
117 | |||
118 | /* set Timer1 reference value based on 125kHz tick */ | ||
119 | TREF1 = ms * 125; | ||
120 | |||
121 | /* single count, zero the counter, divider = 16 [2^(3+1)], enable */ | ||
122 | TCFG1 = (1<<9) | (1<<8) | (3<<4) | 1; | ||
123 | |||
124 | /* wait until Timer1 ref reached */ | ||
125 | while (!(TIREQ & TF1)) {}; | ||
126 | } | ||
127 | |||
128 | |||
129 | static void lcd_display_on(void) | ||
130 | { | ||
131 | /* power on sequence as per the D2 firmware */ | ||
132 | GPIOA_SET = (1<<16); | ||
133 | |||
134 | sleep_ms(10); | ||
135 | |||
136 | lcd_write_reg(1, 0x1D); | ||
137 | lcd_write_reg(2, 0x0); | ||
138 | lcd_write_reg(3, 0x0); | ||
139 | lcd_write_reg(4, 0x0); | ||
140 | lcd_write_reg(5, 0x40A3); | ||
141 | lcd_write_reg(6, 0x0); | ||
142 | lcd_write_reg(7, 0x0); | ||
143 | lcd_write_reg(8, 0x0); | ||
144 | lcd_write_reg(9, 0x0); | ||
145 | lcd_write_reg(10, 0x0); | ||
146 | lcd_write_reg(16, 0x0); | ||
147 | lcd_write_reg(17, 0x0); | ||
148 | lcd_write_reg(18, 0x0); | ||
149 | lcd_write_reg(19, 0x0); | ||
150 | lcd_write_reg(20, 0x0); | ||
151 | lcd_write_reg(21, 0x0); | ||
152 | lcd_write_reg(22, 0x0); | ||
153 | lcd_write_reg(23, 0x0); | ||
154 | lcd_write_reg(24, 0x0); | ||
155 | lcd_write_reg(25, 0x0); | ||
156 | sleep_ms(10); | ||
157 | |||
158 | lcd_write_reg(9, 0x4055); | ||
159 | lcd_write_reg(10, 0x0); | ||
160 | sleep_ms(40); | ||
161 | |||
162 | lcd_write_reg(10, 0x2000); | ||
163 | sleep_ms(40); | ||
164 | |||
165 | lcd_write_reg(1, 0xC01D); | ||
166 | lcd_write_reg(2, 0x204); | ||
167 | lcd_write_reg(3, 0xE100); | ||
168 | lcd_write_reg(4, 0x1000); | ||
169 | lcd_write_reg(5, 0x5033); | ||
170 | lcd_write_reg(6, 0x4); | ||
171 | lcd_write_reg(7, 0x30); | ||
172 | lcd_write_reg(8, 0x41C); | ||
173 | lcd_write_reg(16, 0x207); | ||
174 | lcd_write_reg(17, 0x702); | ||
175 | lcd_write_reg(18, 0xB05); | ||
176 | lcd_write_reg(19, 0xB05); | ||
177 | lcd_write_reg(20, 0x707); | ||
178 | lcd_write_reg(21, 0x507); | ||
179 | lcd_write_reg(22, 0x103); | ||
180 | lcd_write_reg(23, 0x406); | ||
181 | lcd_write_reg(24, 0x2); | ||
182 | lcd_write_reg(25, 0x0); | ||
183 | sleep_ms(60); | ||
184 | |||
185 | lcd_write_reg(9, 0xA55); | ||
186 | lcd_write_reg(10, 0x111F); | ||
187 | sleep_ms(10); | ||
188 | |||
189 | pcf50606_write_reg(0x35, 0xe9); /* PWMC1 - backlight power (intensity) */ | ||
190 | pcf50606_write_reg(0x38, 0x3); /* GPOC1 - ? */ | ||
191 | |||
192 | /* tell that we're on now */ | ||
193 | display_on = true; | ||
194 | } | ||
195 | |||
196 | static void lcd_display_off(void) | ||
197 | { | ||
198 | /* block drawing operations and changing of first */ | ||
199 | display_on = false; | ||
200 | |||
201 | /* LQV shutdown sequence */ | ||
202 | lcd_write_reg(9, 0x55); | ||
203 | lcd_write_reg(10, 0x1417); | ||
204 | lcd_write_reg(5, 0x4003); | ||
205 | sleep_ms(10); | ||
206 | |||
207 | lcd_write_reg(9, 0x0); | ||
208 | sleep_ms(10); | ||
209 | |||
210 | /* kill power to LCD panel (unconfirmed) */ | ||
211 | GPIOA_CLEAR = (1<<16); | ||
212 | |||
213 | /* also kill the backlight, otherwise LCD fade is visible on screen */ | ||
214 | GPIOA_CLEAR = (1<<6); | ||
215 | } | ||
216 | |||
217 | |||
218 | void lcd_enable(bool on) | ||
219 | { | ||
220 | if (on == display_on) | ||
221 | return; | ||
222 | |||
223 | if (on) | ||
224 | { | ||
225 | lcd_display_on(); /* Turn on display */ | ||
226 | lcd_update(); /* Resync display */ | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | lcd_display_off(); /* Turn off display */ | ||
231 | } | ||
232 | } | ||
233 | |||
234 | bool lcd_enabled(void) | ||
235 | { | ||
236 | return display_on; | ||
237 | } | ||
238 | |||
239 | |||
240 | void lcd_init_device(void) | ||
241 | { | ||
242 | BCLKCTR |= 4; /* enable LCD bus clock */ | ||
243 | |||
244 | /* set PCK_LCD to 108Mhz */ | ||
245 | PCLK_LCD &= ~PCK_EN; | ||
246 | PCLK_LCD = PCK_EN | (CKSEL_PLL1<<24) | 1; /* source = PLL1, divided by 2 */ | ||
247 | |||
248 | /* reset the LCD controller */ | ||
249 | SWRESET |= 4; | ||
250 | SWRESET &= ~4; | ||
251 | |||
252 | /* set port configuration */ | ||
253 | PORTCFG1 &= ~0xC0000000; | ||
254 | PORTCFG1 &= ~0x3FC0; | ||
255 | PORTCFG2 &= ~0x100; | ||
256 | |||
257 | /* set physical display size */ | ||
258 | LCDC_DS = (LCD_HEIGHT<<16) | LCD_WIDTH; | ||
259 | |||
260 | LCDC_HTIME1 = (0x2d<<16) | 0x3bf; | ||
261 | LCDC_HTIME2 = (1<<16) | 1; | ||
262 | LCDC_VTIME1 = LCDC_VTIME3 = (0<<16) | 239; | ||
263 | LCDC_VTIME2 = LCDC_VTIME4 = (1<<16) | 3; | ||
264 | |||
265 | LCDC_I1BASE = (unsigned int)lcd_framebuffer; /* dirty, dirty hack */ | ||
266 | LCDC_I1SIZE = (LCD_HEIGHT<<16) | LCD_WIDTH; /* image 1 size */ | ||
267 | //LCDC_I1POS = (0<<16) | 0; /* position */ | ||
268 | //LCDC_I1OFF = 0; /* address offset */ | ||
269 | //LCDC_I1SCALE = 0; /* scaling */ | ||
270 | LCDC_I1CTRL = 5; /* 565bpp (7 = 888bpp) */ | ||
271 | //LCDC_CTRL &= ~(1<<28); | ||
272 | |||
273 | LCDC_CLKDIV = (LCDC_CLKDIV &~ 0xFF00FF) | (1<<16) | 2; /* and this means? */ | ||
274 | |||
275 | /* set and clear various flags - not investigated yet */ | ||
276 | //LCDC_CTRL &~ 0x090006AA; /* clear bits 1,3,5,7,9,10,24,27 */ | ||
277 | LCDC_CTRL |= 0x02800144; /* set bits 2,6,8,25,23 */ | ||
278 | LCDC_CTRL = (LCDC_CTRL &~ 0xF0000) | 0x20000; | ||
279 | //LCDC_CTRL = (LCDC_CTRL &~ 0x700000) | 0x700000; | ||
280 | |||
281 | /* enable LCD controller */ | ||
282 | LCDC_CTRL |= 1; | ||
283 | } | ||
284 | |||
285 | |||
286 | /*** Update functions ***/ | ||
287 | |||
288 | |||
289 | /* Update the display. | ||
290 | This must be called after all other LCD functions that change the display. */ | ||
291 | void lcd_update(void) ICODE_ATTR; | ||
292 | void lcd_update(void) | ||
293 | { | ||
294 | #warning function not implemented | ||
295 | /* currently lcd_framebuffer is accessed directly by the hardware */ | ||
296 | } | ||
297 | |||
298 | /* Update a fraction of the display. */ | ||
299 | void lcd_update_rect(int, int, int, int) ICODE_ATTR; | ||
300 | void lcd_update_rect(int x, int y, int width, int height) | ||
301 | { | ||
302 | #warning function not implemented | ||
303 | (void)x; | ||
304 | (void)y; | ||
305 | (void)width; | ||
306 | (void)height; | ||
307 | } | ||
308 | |||
309 | void lcd_set_flip(bool yesno) | ||
310 | { | ||
311 | #warning function not implemented | ||
312 | (void)yesno; | ||
313 | } | ||
314 | |||
315 | void lcd_set_invert_display(bool yesno) | ||
316 | { | ||
317 | #warning function not implemented | ||
318 | (void)yesno; | ||
319 | } | ||
320 | |||
321 | void lcd_blit(const fb_data* data, int bx, int y, int bwidth, | ||
322 | int height, int stride) | ||
323 | { | ||
324 | #warning function not implemented | ||
325 | (void)data; | ||
326 | (void)bx; | ||
327 | (void)y; | ||
328 | (void)bwidth; | ||
329 | (void)height; | ||
330 | (void)stride; | ||
331 | } | ||
332 | |||
333 | void lcd_yuv_blit(unsigned char * const src[3], | ||
334 | int src_x, int src_y, int stride, | ||
335 | int x, int y, int width, int height) | ||
336 | { | ||
337 | #warning function not implemented | ||
338 | (void)src; | ||
339 | (void)src_x; | ||
340 | (void)src_y; | ||
341 | (void)stride; | ||
342 | (void)x; | ||
343 | (void)y; | ||
344 | (void)width; | ||
345 | (void)height; | ||
346 | } | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c b/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c new file mode 100644 index 0000000000..2d50f042d9 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/pcm-cowond2.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Karl Kurbjun | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "system.h" | ||
20 | #include "kernel.h" | ||
21 | #include "logf.h" | ||
22 | #include "audio.h" | ||
23 | #include "sound.h" | ||
24 | #include "file.h" | ||
25 | |||
26 | void pcm_postinit(void) | ||
27 | { | ||
28 | #warning function not implemented | ||
29 | } | ||
30 | |||
31 | const void * pcm_play_dma_get_peak_buffer(int *count) | ||
32 | { | ||
33 | #warning function not implemented | ||
34 | (void) count; | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | void pcm_play_dma_init(void) | ||
39 | { | ||
40 | #warning function not implemented | ||
41 | } | ||
42 | |||
43 | void pcm_apply_settings(void) | ||
44 | { | ||
45 | #warning function not implemented | ||
46 | } | ||
47 | |||
48 | void pcm_set_frequency(unsigned int frequency) | ||
49 | { | ||
50 | #warning function not implemented | ||
51 | (void) frequency; | ||
52 | } | ||
53 | |||
54 | void pcm_play_dma_start(const void *addr, size_t size) | ||
55 | { | ||
56 | #warning function not implemented | ||
57 | (void) addr; | ||
58 | (void) size; | ||
59 | } | ||
60 | |||
61 | void pcm_play_dma_stop(void) | ||
62 | { | ||
63 | #warning function not implemented | ||
64 | } | ||
65 | |||
66 | void pcm_play_lock(void) | ||
67 | { | ||
68 | #warning function not implemented | ||
69 | } | ||
70 | |||
71 | void pcm_play_unlock(void) | ||
72 | { | ||
73 | #warning function not implemented | ||
74 | } | ||
75 | |||
76 | void pcm_play_dma_pause(bool pause) | ||
77 | { | ||
78 | #warning function not implemented | ||
79 | (void) pause; | ||
80 | } | ||
81 | |||
82 | size_t pcm_get_bytes_waiting(void) | ||
83 | { | ||
84 | #warning function not implemented | ||
85 | return 0; | ||
86 | } | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/power-cowond2.c b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c new file mode 100644 index 0000000000..d8a58570e4 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/power-cowond2.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include <stdbool.h> | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "power.h" | ||
25 | |||
26 | #ifndef SIMULATOR | ||
27 | |||
28 | void power_init(void) | ||
29 | { | ||
30 | #warning function not implemented | ||
31 | } | ||
32 | |||
33 | void ide_power_enable(bool on) | ||
34 | { | ||
35 | #warning function not implemented | ||
36 | (void)on; | ||
37 | } | ||
38 | |||
39 | bool ide_powered(void) | ||
40 | { | ||
41 | #warning function not implemented | ||
42 | return true; | ||
43 | } | ||
44 | |||
45 | void power_off(void) | ||
46 | { | ||
47 | #warning function not implemented | ||
48 | } | ||
49 | |||
50 | #else /* SIMULATOR */ | ||
51 | |||
52 | bool charger_inserted(void) | ||
53 | { | ||
54 | return false; | ||
55 | } | ||
56 | |||
57 | void charger_enable(bool on) | ||
58 | { | ||
59 | (void)on; | ||
60 | } | ||
61 | |||
62 | void power_off(void) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | void ide_power_enable(bool on) | ||
67 | { | ||
68 | (void)on; | ||
69 | } | ||
70 | |||
71 | #endif /* SIMULATOR */ | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c b/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c new file mode 100644 index 0000000000..b3572307e9 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/powermgmt-cowond2.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Karl Kurbjun | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "adc.h" | ||
22 | #include "powermgmt.h" | ||
23 | #include "kernel.h" | ||
24 | |||
25 | unsigned short current_voltage = 3910; | ||
26 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
27 | { | ||
28 | 0 | ||
29 | }; | ||
30 | |||
31 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
32 | { | ||
33 | 0 | ||
34 | }; | ||
35 | |||
36 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
37 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
38 | { | ||
39 | { 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320 }, | ||
40 | }; | ||
41 | |||
42 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
43 | const unsigned short percent_to_volt_charge[11] = | ||
44 | { | ||
45 | 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320, | ||
46 | }; | ||
47 | |||
48 | void read_battery_inputs(void) | ||
49 | { | ||
50 | #warning function not implemented | ||
51 | } | ||
52 | |||
53 | /* Returns battery voltage from ADC [millivolts] */ | ||
54 | unsigned int battery_adc_voltage(void) | ||
55 | { | ||
56 | #warning function not implemented | ||
57 | return 0; | ||
58 | } | ||
59 | |||
diff --git a/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c b/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c new file mode 100644 index 0000000000..6ec903b917 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/usb-cowond2.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | #include "system.h" | ||
23 | #include "kernel.h" | ||
24 | #include "ata.h" | ||
25 | |||
26 | /* USB detect is GPIOC 26 active low */ | ||
27 | inline bool usb_detect(void) | ||
28 | { | ||
29 | return (GPIOC & 1<<26)?false:true; | ||
30 | } | ||
31 | |||
32 | void usb_init_device(void) | ||
33 | { | ||
34 | #warning function not implemented | ||
35 | } | ||
36 | |||
37 | void usb_enable(bool on) | ||
38 | { | ||
39 | #warning function not implemented | ||
40 | |||
41 | if (on) | ||
42 | { | ||
43 | |||
44 | } | ||
45 | else | ||
46 | { | ||
47 | |||
48 | } | ||
49 | } | ||
diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S new file mode 100644 index 0000000000..6e092bcd82 --- /dev/null +++ b/firmware/target/arm/tcc780x/crt0.S | |||
@@ -0,0 +1,304 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | ||
21 | * | ||
22 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) | ||
23 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "config.h" | ||
28 | #include "cpu.h" | ||
29 | |||
30 | .section .init.text,"ax",%progbits | ||
31 | |||
32 | .global start | ||
33 | |||
34 | /* Telechips firmware files start with a 32-byte header, as part of the code. */ | ||
35 | |||
36 | start: | ||
37 | #ifdef TCCBOOT | ||
38 | /* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to | ||
39 | enable building the bootloader to be appended to the end of the | ||
40 | original firmware, dual-booting based on a key-press. | ||
41 | |||
42 | NB: On the D2 TCCBOOT currently only works in USB boot mode (via tcctool) | ||
43 | When flashed to the device, the OF will boot as normal - but holding a | ||
44 | key to boot Rockbox results in a blank screen and crashed player. | ||
45 | |||
46 | The following two values are filled in by mktccboot. | ||
47 | */ | ||
48 | .word 0 /* Saved entrypoint of original firmware*/ | ||
49 | .word 0 /* Location in RAM of the start of our bootloader */ | ||
50 | #else | ||
51 | ldr pc, =start_loc /* jump to the main entry point */ | ||
52 | |||
53 | .word 0xffff0601 /* Unknown magic */ | ||
54 | .word 0x3a726556 /* "Ver:" */ | ||
55 | .word 0x31373030 /* "0071" */ | ||
56 | .word 0 /* First CRC32 */ | ||
57 | .word 0 /* Unknown - always 0 */ | ||
58 | .word 0 /* Second CRC32 */ | ||
59 | .word 0 /* length of firmware file */ | ||
60 | |||
61 | #ifdef COWON_D2 | ||
62 | /* Some original firmwares have 0x40 bytes of zeroes here - we | ||
63 | don't know why, but err on the side of caution and include it | ||
64 | here. */ | ||
65 | .space 0x40 | ||
66 | #endif | ||
67 | #endif | ||
68 | |||
69 | start_loc: | ||
70 | |||
71 | #ifdef BOOTLOADER | ||
72 | #ifdef TCCBOOT | ||
73 | #ifdef COWON_D2 | ||
74 | ldr r0, =0xf005a000 | ||
75 | ldr r0, [r0, #0x40] /* Read GPIO B */ | ||
76 | tst r0, #0x4 | ||
77 | ldreq pc, [pc, #-28] /* Jump to original firmware if keypad not pressed */ | ||
78 | #else | ||
79 | #error No bootup key detection implemented for this target | ||
80 | #endif | ||
81 | |||
82 | /* Copy bootloader to safe area - 0x21000000 (DRAM) */ | ||
83 | /* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */ | ||
84 | ldr r0, [pc, #-28] | ||
85 | mov r1, #0x22000000 | ||
86 | sub r1, r1, #0x100000 | ||
87 | ldr r2, =_dataend | ||
88 | 1: | ||
89 | cmp r2, r1 | ||
90 | ldrhi r3, [r0], #4 | ||
91 | strhi r3, [r1], #4 | ||
92 | bhi 1b | ||
93 | |||
94 | ldr pc, =copied_start /* jump to the relocated start_loc: */ | ||
95 | |||
96 | copied_start: | ||
97 | #endif | ||
98 | #else | ||
99 | /* We don't use interrupts in the bootloader */ | ||
100 | |||
101 | /* Set up stack for IRQ mode */ | ||
102 | mov r0,#0xd2 | ||
103 | msr cpsr, r0 | ||
104 | ldr sp, =irq_stack | ||
105 | /* Set up stack for FIQ mode */ | ||
106 | mov r0,#0xd1 | ||
107 | msr cpsr, r0 | ||
108 | ldr sp, =fiq_stack | ||
109 | |||
110 | /* Let abort and undefined modes use IRQ stack */ | ||
111 | mov r0,#0xd7 | ||
112 | msr cpsr, r0 | ||
113 | ldr sp, =irq_stack | ||
114 | mov r0,#0xdb | ||
115 | msr cpsr, r0 | ||
116 | ldr sp, =irq_stack | ||
117 | #endif | ||
118 | |||
119 | /* Switch to supervisor mode */ | ||
120 | mov r0,#0xd3 | ||
121 | msr cpsr, r0 | ||
122 | ldr sp, =stackend | ||
123 | |||
124 | |||
125 | #if !defined(BOOTLOADER) && !defined(STUB) | ||
126 | |||
127 | /* Copy exception handler code to address 0 */ | ||
128 | ldr r2, =_vectorsstart | ||
129 | ldr r3, =_vectorsend | ||
130 | ldr r4, =_vectorscopy | ||
131 | 1: | ||
132 | cmp r3, r2 | ||
133 | ldrhi r5, [r4], #4 | ||
134 | strhi r5, [r2], #4 | ||
135 | bhi 1b | ||
136 | |||
137 | /* Zero out IBSS */ | ||
138 | ldr r2, =_iedata | ||
139 | ldr r3, =_iend | ||
140 | mov r4, #0 | ||
141 | 1: | ||
142 | cmp r3, r2 | ||
143 | strhi r4, [r2], #4 | ||
144 | bhi 1b | ||
145 | |||
146 | /* Copy the ITCM */ | ||
147 | ldr r2, =_itcmcopy | ||
148 | ldr r3, =_itcmstart | ||
149 | ldr r4, =_itcmend | ||
150 | 1: | ||
151 | cmp r4, r3 | ||
152 | ldrhi r5, [r2], #4 | ||
153 | strhi r5, [r3], #4 | ||
154 | bhi 1b | ||
155 | |||
156 | /* Copy the DTCM */ | ||
157 | ldr r2, =_dtcmcopy | ||
158 | ldr r3, =_dtcmstart | ||
159 | ldr r4, =_dtcmend | ||
160 | 1: | ||
161 | cmp r4, r3 | ||
162 | ldrhi r5, [r2], #4 | ||
163 | strhi r5, [r3], #4 | ||
164 | bhi 1b | ||
165 | #endif /* !BOOTLOADER,!STUB */ | ||
166 | |||
167 | /* Initialise bss section to zero */ | ||
168 | ldr r2, =_edata | ||
169 | ldr r3, =_end | ||
170 | mov r4, #0 | ||
171 | 1: | ||
172 | cmp r3, r2 | ||
173 | strhi r4, [r2], #4 | ||
174 | bhi 1b | ||
175 | |||
176 | /* Set up some stack and munge it with 0xdeadbeef */ | ||
177 | ldr sp, =stackend | ||
178 | mov r3, sp | ||
179 | ldr r2, =stackbegin | ||
180 | ldr r4, =0xdeadbeef | ||
181 | 1: | ||
182 | cmp r3, r2 | ||
183 | strhi r4, [r2], #4 | ||
184 | bhi 1b | ||
185 | |||
186 | /* | ||
187 | Enable cache & TCM regions | ||
188 | TODO: This is just doing what the OF does at present. It needs to be | ||
189 | better understood and moved out to a separate MMU functions package. | ||
190 | */ | ||
191 | ldr r1, =0x1fe0c | ||
192 | mov r0, #0xf7000000 | ||
193 | str r1, [r0] | ||
194 | ldr r1, =0x2801ae24 | ||
195 | str r1, [r0,#4] | ||
196 | ldr r1, =0x13e44 | ||
197 | str r1, [r0,#8] | ||
198 | ldr r1, =0x4001ce60 | ||
199 | str r1, [r0,#0xc] | ||
200 | ldr r1, =0x6001be80 | ||
201 | str r1, [r0,#0x10] | ||
202 | ldr r1, =0x3801aea4 | ||
203 | str r1, [r0,#0x14] | ||
204 | ldr r1, =0x8001eec0 | ||
205 | str r1, [r0,#0x18] | ||
206 | ldr r1, =0x1001aee0 | ||
207 | str r1, [r0,#0x1c] | ||
208 | add r1, r0, #0x8000 /* r1 now = 0xf7008000 */ | ||
209 | ldr r0, =0xa0000011 | ||
210 | ldr r2, =0x5507d | ||
211 | mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */ | ||
212 | mov r0, #0xd | ||
213 | mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */ | ||
214 | ldr r0, =0x55555555 | ||
215 | mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */ | ||
216 | mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */ | ||
217 | mov r0, #0 | ||
218 | mcr p15, 0, r0,c7,c5 /* invalidate icache */ | ||
219 | mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */ | ||
220 | mcr p15, 0, r0,c7,c6 /* invalidate dcache */ | ||
221 | mcr p15, 0, r1,c8,c7 /* invalidate tlb */ | ||
222 | |||
223 | bl main | ||
224 | /* main() should never return */ | ||
225 | |||
226 | #ifndef BOOTLOADER | ||
227 | |||
228 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | ||
229 | .section .vectors,"aw" | ||
230 | ldr pc, [pc, #24] | ||
231 | ldr pc, [pc, #24] | ||
232 | ldr pc, [pc, #24] | ||
233 | ldr pc, [pc, #24] | ||
234 | ldr pc, [pc, #24] | ||
235 | ldr pc, [pc, #24] | ||
236 | ldr pc, [pc, #24] | ||
237 | ldr pc, [pc, #24] | ||
238 | |||
239 | /* Exception vectors */ | ||
240 | .global vectors | ||
241 | vectors: | ||
242 | .word start | ||
243 | .word undef_instr_handler | ||
244 | .word software_int_handler | ||
245 | .word prefetch_abort_handler | ||
246 | .word data_abort_handler | ||
247 | .word reserved_handler | ||
248 | .word irq_handler | ||
249 | .word fiq_handler | ||
250 | |||
251 | .text | ||
252 | |||
253 | #if !defined(STUB) | ||
254 | .global irq | ||
255 | .global fiq | ||
256 | .global UIE | ||
257 | #endif | ||
258 | |||
259 | /* All illegal exceptions call into UIE with exception address as first | ||
260 | parameter. This is calculated differently depending on which exception | ||
261 | we're in. Second parameter is exception number, used for a string lookup | ||
262 | in UIE. | ||
263 | */ | ||
264 | undef_instr_handler: | ||
265 | mov r0, lr | ||
266 | mov r1, #0 | ||
267 | b UIE | ||
268 | |||
269 | /* We run supervisor mode most of the time, and should never see a software | ||
270 | exception being thrown. Perhaps make it illegal and call UIE? | ||
271 | */ | ||
272 | software_int_handler: | ||
273 | reserved_handler: | ||
274 | movs pc, lr | ||
275 | |||
276 | prefetch_abort_handler: | ||
277 | sub r0, lr, #4 | ||
278 | mov r1, #1 | ||
279 | b UIE | ||
280 | |||
281 | data_abort_handler: | ||
282 | sub r0, lr, #8 | ||
283 | mov r1, #2 | ||
284 | b UIE | ||
285 | |||
286 | #if defined(STUB) | ||
287 | UIE: | ||
288 | b UIE | ||
289 | #endif | ||
290 | |||
291 | /* We don't use interrupts in the bootloader */ | ||
292 | |||
293 | /* Align stacks to cache line boundary */ | ||
294 | .balign 16 | ||
295 | |||
296 | /* 256 words of IRQ stack */ | ||
297 | .space 256*4 | ||
298 | irq_stack: | ||
299 | |||
300 | /* 256 words of FIQ stack */ | ||
301 | .space 256*4 | ||
302 | fiq_stack: | ||
303 | |||
304 | #endif | ||
diff --git a/firmware/target/arm/tcc780x/debug-tcc780x.c b/firmware/target/arm/tcc780x/debug-tcc780x.c new file mode 100644 index 0000000000..cc5716fd88 --- /dev/null +++ b/firmware/target/arm/tcc780x/debug-tcc780x.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | #include "system.h" | ||
23 | #include "string.h" | ||
24 | #include <stdbool.h> | ||
25 | #include "button.h" | ||
26 | #include "lcd.h" | ||
27 | #include "sprintf.h" | ||
28 | #include "font.h" | ||
29 | |||
30 | bool __dbg_ports(void); | ||
31 | bool __dbg_ports(void) | ||
32 | { | ||
33 | return false; | ||
34 | } | ||
35 | |||
36 | //extern char r_buffer[5]; | ||
37 | //extern int r_button; | ||
38 | |||
39 | bool __dbg_hw_info(void); | ||
40 | bool __dbg_hw_info(void) | ||
41 | { | ||
42 | int line = 0, button, oldline; | ||
43 | int *address=0x0; | ||
44 | bool done=false; | ||
45 | char buf[100]; | ||
46 | |||
47 | lcd_setmargins(0, 0); | ||
48 | lcd_setfont(FONT_SYSFIXED); | ||
49 | lcd_clear_display(); | ||
50 | |||
51 | /* Put all the static text before the while loop */ | ||
52 | lcd_puts(0, line++, "[Hardware info]"); | ||
53 | |||
54 | /* TODO: ... */ | ||
55 | |||
56 | line++; | ||
57 | oldline=line; | ||
58 | while(!done) | ||
59 | { | ||
60 | line = oldline; | ||
61 | button = button_get(false); | ||
62 | |||
63 | button &= ~BUTTON_REPEAT; | ||
64 | |||
65 | if (button == BUTTON_MENU) | ||
66 | done=true; | ||
67 | if(button==BUTTON_DOWN) | ||
68 | address+=0x01; | ||
69 | else if (button==BUTTON_UP) | ||
70 | address-=0x01; | ||
71 | |||
72 | /*snprintf(buf, sizeof(buf), "Buffer: 0x%02x%02x%02x%02x%02x", | ||
73 | r_buffer[0], r_buffer[1], r_buffer[2], r_buffer[3],r_buffer[4] ); lcd_puts(0, line++, buf); | ||
74 | snprintf(buf, sizeof(buf), "Button: 0x%08x, HWread: 0x%08x", | ||
75 | (unsigned int)button, r_button); lcd_puts(0, line++, buf);*/ | ||
76 | snprintf(buf, sizeof(buf), "current tick: %08x Seconds running: %08d", | ||
77 | (unsigned int)current_tick, (unsigned int)current_tick/100); lcd_puts(0, line++, buf); | ||
78 | snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x", | ||
79 | (unsigned int)address, *address); lcd_puts(0, line++, buf); | ||
80 | snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x", | ||
81 | (unsigned int)(address+1), *(address+1)); lcd_puts(0, line++, buf); | ||
82 | snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x", | ||
83 | (unsigned int)(address+2), *(address+2)); lcd_puts(0, line++, buf); | ||
84 | |||
85 | lcd_update(); | ||
86 | } | ||
87 | return false; | ||
88 | } | ||
diff --git a/firmware/target/arm/tcc780x/kernel-tcc780x.c b/firmware/target/arm/tcc780x/kernel-tcc780x.c new file mode 100644 index 0000000000..e0d9c3342e --- /dev/null +++ b/firmware/target/arm/tcc780x/kernel-tcc780x.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "system.h" | ||
22 | #include "kernel.h" | ||
23 | #include "timer.h" | ||
24 | #include "thread.h" | ||
25 | |||
26 | /* NB: PCK_TCT must previously have been set to 2Mhz by calling clock_init() */ | ||
27 | void tick_start(unsigned int interval_in_ms) | ||
28 | { | ||
29 | /* disable Timer0 */ | ||
30 | TCFG0 &= ~1; | ||
31 | |||
32 | /* set counter reference value based on 1Mhz tick */ | ||
33 | TREF0 = interval_in_ms * 1000; | ||
34 | |||
35 | /* Timer0 = reset to 0, divide=2, IRQ enable, enable (continuous) */ | ||
36 | TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1; | ||
37 | |||
38 | /* Unmask timer IRQ */ | ||
39 | MIRQ &= ~TIMER_IRQ_MASK; | ||
40 | } | ||
41 | |||
42 | /* NB: Since the 7801 has a single timer IRQ, the tick tasks are dispatched | ||
43 | as part of the central timer IRQ processing in timer-tcc780x.c */ | ||
diff --git a/firmware/target/arm/tcc780x/system-target.h b/firmware/target/arm/tcc780x/system-target.h new file mode 100644 index 0000000000..15508bc8bf --- /dev/null +++ b/firmware/target/arm/tcc780x/system-target.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef SYSTEM_TARGET_H | ||
20 | #define SYSTEM_TARGET_H | ||
21 | |||
22 | #include "system-arm.h" | ||
23 | |||
24 | #define CPUFREQ_DEFAULT 98784000 | ||
25 | #define CPUFREQ_NORMAL 98784000 | ||
26 | #define CPUFREQ_MAX 192000000 | ||
27 | |||
28 | #define inl(a) (*(volatile unsigned long *) (a)) | ||
29 | #define outl(a,b) (*(volatile unsigned long *) (b) = (a)) | ||
30 | #define inb(a) (*(volatile unsigned char *) (a)) | ||
31 | #define outb(a,b) (*(volatile unsigned char *) (b) = (a)) | ||
32 | #define inw(a) (*(volatile unsigned short *) (a)) | ||
33 | #define outw(a,b) (*(volatile unsigned short *) (b) = (a)) | ||
34 | |||
35 | #endif /* SYSTEM_TARGET_H */ | ||
diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c new file mode 100644 index 0000000000..30221d180e --- /dev/null +++ b/firmware/target/arm/tcc780x/system-tcc780x.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "kernel.h" | ||
21 | #include "system.h" | ||
22 | #include "panic.h" | ||
23 | |||
24 | #if !defined(BOOTLOADER) | ||
25 | |||
26 | #define default_interrupt(name) \ | ||
27 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | ||
28 | |||
29 | void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); | ||
30 | void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked)); | ||
31 | |||
32 | default_interrupt(EXT0); | ||
33 | default_interrupt(EXT1); | ||
34 | default_interrupt(EXT2); | ||
35 | default_interrupt(EXT3); | ||
36 | default_interrupt(IRQ4); | ||
37 | default_interrupt(IRQ5); | ||
38 | default_interrupt(TIMER); | ||
39 | default_interrupt(IRQ7); | ||
40 | default_interrupt(IRQ8); | ||
41 | default_interrupt(IRQ9); | ||
42 | default_interrupt(IRQ10); | ||
43 | default_interrupt(IRQ11); | ||
44 | default_interrupt(IRQ12); | ||
45 | default_interrupt(IRQ13); | ||
46 | default_interrupt(DAI_RX); | ||
47 | default_interrupt(DAI_TX); | ||
48 | default_interrupt(IRQ16); | ||
49 | default_interrupt(IRQ17); | ||
50 | default_interrupt(IRQ18); | ||
51 | default_interrupt(IRQ19); | ||
52 | default_interrupt(IRQ20); | ||
53 | default_interrupt(IRQ21); | ||
54 | default_interrupt(IRQ22); | ||
55 | default_interrupt(IRQ23); | ||
56 | default_interrupt(IRQ24); | ||
57 | default_interrupt(IRQ25); | ||
58 | default_interrupt(IRQ26); | ||
59 | default_interrupt(IRQ27); | ||
60 | default_interrupt(IRQ28); | ||
61 | default_interrupt(IRQ29); | ||
62 | default_interrupt(IRQ30); | ||
63 | default_interrupt(IRQ31); | ||
64 | |||
65 | static void (* const irqvector[])(void) = | ||
66 | { | ||
67 | EXT0,EXT1,EXT2,EXT3,IRQ4,IRQ5,TIMER,IRQ7, | ||
68 | IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,DAI_RX,DAI_TX, | ||
69 | IRQ16,IRQ17,IRQ18,IRQ19,IRQ20,IRQ21,IRQ22,IRQ23, | ||
70 | IRQ24,IRQ25,IRQ26,IRQ27,IRQ28,IRQ29,IRQ30,IRQ31 | ||
71 | }; | ||
72 | |||
73 | static const char * const irqname[] = | ||
74 | { | ||
75 | "EXT0","EXT1","EXT2","EXT3","IRQ4","IRQ5","TIMER","IRQ7", | ||
76 | "IRQ8","IRQ9","IRQ10","IRQ11","IRQ12","IRQ13","DAI_RX","DAI_TX", | ||
77 | "IRQ16","IRQ17","IRQ18","IRQ19","IRQ20","IRQ21","IRQ22","IRQ23", | ||
78 | "IRQ24","IRQ25","IRQ26","IRQ27","IRQ28","IRQ29","IRQ30","IRQ31" | ||
79 | }; | ||
80 | |||
81 | static void UIRQ(void) | ||
82 | { | ||
83 | unsigned int offset = VNIRQ; | ||
84 | panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); | ||
85 | } | ||
86 | |||
87 | void irq_handler(void) | ||
88 | { | ||
89 | /* | ||
90 | * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c | ||
91 | */ | ||
92 | |||
93 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ | ||
94 | "sub sp, sp, #8 \n"); /* Reserve stack */ | ||
95 | irqvector[VNIRQ](); | ||
96 | asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ | ||
97 | "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ | ||
98 | "subs pc, lr, #4 \n"); /* Return from FIQ */ | ||
99 | } | ||
100 | |||
101 | void fiq_handler(void) | ||
102 | { | ||
103 | asm volatile ( | ||
104 | "sub lr, lr, #4 \r\n" | ||
105 | "movs lr,pc \r\n" | ||
106 | ); | ||
107 | } | ||
108 | #endif /* !defined(BOOTLOADER) */ | ||
109 | |||
110 | |||
111 | /* TODO: | ||
112 | a) this is not the place for this function | ||
113 | b) it currently ignores the supplied frequency and uses default values | ||
114 | c) if the PLL being set drives any PCKs, an appropriate new clock divider | ||
115 | will have to be re-calculated for those PCKs (the OF maintains a list of | ||
116 | PCK frequencies for this purpose). | ||
117 | */ | ||
118 | void set_pll_frequency(unsigned int pll_number, unsigned int frequency) | ||
119 | { | ||
120 | int i = 0; | ||
121 | |||
122 | if (pll_number > 1) return; | ||
123 | |||
124 | /* The frequency parameter is currently ignored and temporary values are | ||
125 | used (PLL0=192Mhz, PLL1=216Mhz). The D2 firmware uses a lookup table | ||
126 | to derive the values of PLLxCFG from a the supplied frequency. | ||
127 | Presumably we will need to do something similar. */ | ||
128 | if (pll_number == 0) | ||
129 | { | ||
130 | /* drive CPU off Xin while switching */ | ||
131 | CLKCTRL = 0xB00FF014; /* Xin enable, Fsys driven by Xin, Fbus = Fsys, | ||
132 | MCPU=Fbus, SCPU=Fbus */ | ||
133 | |||
134 | asm volatile ( | ||
135 | "nop \n\t" | ||
136 | "nop \n\t" | ||
137 | ); | ||
138 | |||
139 | PLL0CFG |= (1<<31); /* power down */ | ||
140 | CLKDIVC = CLKDIVC &~ (0xff << 24); /* disable PLL0 divider */ | ||
141 | PLL0CFG = 0x80019808; /* set for 192Mhz (with power down) */ | ||
142 | PLL0CFG = PLL0CFG &~ (1<<31); /* power up */ | ||
143 | |||
144 | CLKCTRL = (CLKCTRL & ~0x1f) | 0x800FF010; | ||
145 | |||
146 | asm volatile ( | ||
147 | "nop \n\t" | ||
148 | "nop \n\t" | ||
149 | ); | ||
150 | } | ||
151 | else if (pll_number == 1) | ||
152 | { | ||
153 | PLL1CFG |= (1<<31); /* power down */ | ||
154 | CLKDIVC = CLKDIVC &~ (0xff << 16); /* disable PLL1 divider */ | ||
155 | PLL1CFG = 0x80002503; /* set for 216Mhz (with power down)*/ | ||
156 | PLL1CFG = PLL1CFG &~ (1<<31); /* power up */ | ||
157 | } | ||
158 | |||
159 | i = 0x1000; | ||
160 | while (--i) {}; | ||
161 | } | ||
162 | |||
163 | |||
164 | /* TODO - these should live in the target-specific directories and | ||
165 | once we understand what all the GPIO pins do, move the init to the | ||
166 | specific driver for that hardware. For now, we just perform the | ||
167 | same GPIO init as the original firmware - this makes it easier to | ||
168 | investigate what the GPIO pins do. | ||
169 | */ | ||
170 | |||
171 | #ifdef COWON_D2 | ||
172 | static void gpio_init(void) | ||
173 | { | ||
174 | /* Do what the original firmware does */ | ||
175 | GPIOA = 0x07000C83; | ||
176 | GPIOA_DIR = 0x0F010CE3; | ||
177 | GPIOB = 0; | ||
178 | GPIOB_DIR = 0x00080000; | ||
179 | GPIOC = 0x39000000; | ||
180 | GPIOC_DIR = 0xB9000000; | ||
181 | GPIOD = 0; | ||
182 | GPIOD_DIR = 0; | ||
183 | GPIOD = 0; | ||
184 | GPIOD_DIR = 0x00480000; | ||
185 | |||
186 | PORTCFG0 = 0x00034540; | ||
187 | PORTCFG1 = 0x0566A000; | ||
188 | PORTCFG2 = 0x000004C0; | ||
189 | PORTCFG3 = 0x0AA40455; | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | |||
194 | /* Second function called in the original firmware's startup code - we just | ||
195 | set up the clocks in the same way as the original firmware for now. */ | ||
196 | #ifdef COWON_D2 | ||
197 | static void clock_init(void) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | CSCFG3 = (CSCFG3 &~ 0x3fff) | 0x841; | ||
202 | CLKCTRL = (CLKCTRL & ~0xff) | 0x14; | ||
203 | |||
204 | PCLK_RFREQ = 0x1401002d; /* RAM refresh source = Xin (4) / 0x2d = 266kHz */ | ||
205 | |||
206 | MCFG |= 1; | ||
207 | SDCFG = (SDCFG &~ 0x7000) | 0x2000; | ||
208 | |||
209 | MCFG1 |= 1; | ||
210 | SDCFG1 = (SDCFG &~ 0x7000) | 0x2000; | ||
211 | |||
212 | PLL0CFG |= 0x80000000; /* power down */ | ||
213 | PLL0CFG = 0x14010000; /* power up, source = Xin (4) undivided = 12Mhz */ | ||
214 | |||
215 | i = 0x8000; | ||
216 | while (--i) {}; | ||
217 | |||
218 | CLKCTRL = (CLKCTRL &~ 0x1f) | 0x800FF010; /* CPU and COP driven by PLL0 */ | ||
219 | |||
220 | asm volatile ( | ||
221 | "nop \n\t" | ||
222 | "nop \n\t" | ||
223 | ); | ||
224 | |||
225 | /* configure PCK_TCT to 2Mhz (clock source 4 (Xin) divided by 6) */ | ||
226 | PCLK_TCT = PCK_EN | (CKSEL_XIN<<24) | 5; | ||
227 | } | ||
228 | #endif | ||
229 | |||
230 | |||
231 | #ifdef COWON_D2 | ||
232 | void system_init(void) | ||
233 | { | ||
234 | MBCFG = 0x19; | ||
235 | |||
236 | if (TCC780_VER == 0) | ||
237 | ECFG0 = 0x309; | ||
238 | else | ||
239 | ECFG0 = 0x30d; | ||
240 | |||
241 | /* mask all interrupts */ | ||
242 | MIRQ = -1; | ||
243 | |||
244 | gpio_init(); | ||
245 | clock_init(); | ||
246 | |||
247 | /* TODO: these almost certainly shouldn't be here */ | ||
248 | set_pll_frequency(0, 192000000); /* drives CPU */ | ||
249 | set_pll_frequency(1, 216000000); /* drives LCD PXCLK - divided by 2 */ | ||
250 | } | ||
251 | #endif | ||
252 | |||
253 | |||
254 | void system_reboot(void) | ||
255 | { | ||
256 | #warning function not implemented | ||
257 | } | ||
258 | |||
259 | int system_memory_guard(int newmode) | ||
260 | { | ||
261 | #warning function not implemented | ||
262 | |||
263 | (void)newmode; | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
268 | |||
269 | void set_cpu_frequency(long frequency) | ||
270 | { | ||
271 | #warning function not implemented | ||
272 | (void)frequency; | ||
273 | } | ||
274 | |||
275 | #endif | ||
diff --git a/firmware/target/arm/tcc780x/timer-target.h b/firmware/target/arm/tcc780x/timer-target.h new file mode 100644 index 0000000000..db25df7cd4 --- /dev/null +++ b/firmware/target/arm/tcc780x/timer-target.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Karl Kurbjun | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef TIMER_TARGET_H | ||
20 | #define TIMER_TARGET_H | ||
21 | |||
22 | /* timers are based on XIN (12Mhz) */ | ||
23 | #define TIMER_FREQ (12000000) | ||
24 | |||
25 | bool __timer_set(long cycles, bool set); | ||
26 | bool __timer_register(void); | ||
27 | void __timer_unregister(void); | ||
28 | |||
29 | #define __TIMER_SET(cycles, set) \ | ||
30 | __timer_set(cycles, set) | ||
31 | |||
32 | #define __TIMER_REGISTER(reg_prio, unregister_callback, cycles, \ | ||
33 | int_prio, timer_callback) \ | ||
34 | __timer_register() | ||
35 | |||
36 | #define __TIMER_UNREGISTER(...) \ | ||
37 | __timer_unregister() | ||
38 | |||
39 | #endif /* TIMER_TARGET_H */ | ||
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c new file mode 100644 index 0000000000..c724c4b3a8 --- /dev/null +++ b/firmware/target/arm/tcc780x/timer-tcc780x.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | #include "system.h" | ||
23 | #include "timer.h" | ||
24 | #include "logf.h" | ||
25 | |||
26 | /* Use the TC32 counter [sourced by Xin:12Mhz] for this timer, as it's the | ||
27 | only one that allows a 32-bit counter (Timer0-5 are 16/20 bit only). */ | ||
28 | |||
29 | bool __timer_set(long cycles, bool start) | ||
30 | { | ||
31 | #warning function not implemented | ||
32 | |||
33 | (void)cycles; | ||
34 | (void)start; | ||
35 | return false; | ||
36 | } | ||
37 | |||
38 | bool __timer_register(void) | ||
39 | { | ||
40 | #warning function not implemented | ||
41 | |||
42 | return false; | ||
43 | } | ||
44 | |||
45 | void __timer_unregister(void) | ||
46 | { | ||
47 | #warning function not implemented | ||
48 | } | ||
49 | |||
50 | |||
51 | /* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ | ||
52 | |||
53 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | ||
54 | |||
55 | void TIMER(void) | ||
56 | { | ||
57 | if (TIREQ & TF0) /* Timer0 reached ref value */ | ||
58 | { | ||
59 | int i; | ||
60 | |||
61 | /* Run through the list of tick tasks */ | ||
62 | for(i = 0; i < MAX_NUM_TICK_TASKS; i++) | ||
63 | { | ||
64 | if(tick_funcs[i]) | ||
65 | { | ||
66 | tick_funcs[i](); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | current_tick++; | ||
71 | |||
72 | /* reset Timer 0 IRQ & ref flags */ | ||
73 | TIREQ |= TI0 | TF0; | ||
74 | } | ||
75 | |||
76 | if (TC32IRQ & (1<<3)) /* end of TC32 prescale */ | ||
77 | { | ||
78 | /* dispatch timer */ | ||
79 | } | ||
80 | |||
81 | CREQ |= TIMER_IRQ_MASK; /* clear IRQ */ | ||
82 | } | ||