summaryrefslogtreecommitdiff
path: root/firmware/target/sh/archos/recorder
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/sh/archos/recorder')
-rw-r--r--firmware/target/sh/archos/recorder/adc-target.h41
-rw-r--r--firmware/target/sh/archos/recorder/backlight-target.h51
-rw-r--r--firmware/target/sh/archos/recorder/button-recorder.c110
-rw-r--r--firmware/target/sh/archos/recorder/button-target.h59
-rw-r--r--firmware/target/sh/archos/recorder/power-recorder.c107
-rw-r--r--firmware/target/sh/archos/recorder/powermgmt-recorder.c501
-rw-r--r--firmware/target/sh/archos/recorder/powermgmt-target.h89
-rw-r--r--firmware/target/sh/archos/recorder/usb-recorder.c49
8 files changed, 0 insertions, 1007 deletions
diff --git a/firmware/target/sh/archos/recorder/adc-target.h b/firmware/target/sh/archos/recorder/adc-target.h
deleted file mode 100644
index 06c48a5021..0000000000
--- a/firmware/target/sh/archos/recorder/adc-target.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _ADC_TARGET_H_
22#define _ADC_TARGET_H_
23
24#define NUM_ADC_CHANNELS 8
25
26/* normal JBR channel assignment */
27#define ADC_BATTERY 0 /* Battery voltage always reads 0x3FF due to
28 silly scaling */
29#define ADC_CHARGE_REGULATOR 1 /* Regulator reference voltage, should read
30 about 0x1c0 when charging, else 0x3FF */
31#define ADC_USB_POWER 2 /* USB, reads 0x3FF when USB is inserted */
32#define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different
33 voltages for different keys */
34#define ADC_BUTTON_ROW2 5 /* Used for scanning the keys, different
35 voltages for different keys */
36#define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */
37#define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */
38
39#define EXT_SCALE_FACTOR 14800
40
41#endif /* _ADC_TARGET_H_ */
diff --git a/firmware/target/sh/archos/recorder/backlight-target.h b/firmware/target/sh/archos/recorder/backlight-target.h
deleted file mode 100644
index c3dd395eca..0000000000
--- a/firmware/target/sh/archos/recorder/backlight-target.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef BACKLIGHT_TARGET_H
22#define BACKLIGHT_TARGET_H
23
24#include "config.h"
25#include "rtc.h"
26
27#define backlight_hw_init() true
28
29static inline void backlight_hw_on(void)
30{
31 rtc_write(0x13, 0x10); /* 32 kHz square wave */
32 rtc_write(0x0a, rtc_read(0x0a) | 0x40); /* Enable square wave */
33}
34
35static inline void backlight_hw_off(void)
36{
37 /* While on, backlight is flashing at 32 kHz. If the square wave output
38 is disabled while the backlight is lit, it will become constantly lit,
39 (brighter) and slowly fade. This resets the square wave counter and
40 results in the unlit state */
41 unsigned char rtc_0a = rtc_read(0x0a) & ~0x40;
42 rtc_write(0x0a, rtc_0a); /* Disable square wave */
43 rtc_write(0x13, 0xF0); /* 1 Hz square wave */
44 rtc_write(0x0a, rtc_0a | 0x40); /* Enable square wave */
45
46 /* When the square wave output is disabled in the unlit state,
47 the backlight stays off */
48 rtc_write(0x0a, rtc_0a);
49}
50
51#endif
diff --git a/firmware/target/sh/archos/recorder/button-recorder.c b/firmware/target/sh/archos/recorder/button-recorder.c
deleted file mode 100644
index 5e5e67487d..0000000000
--- a/firmware/target/sh/archos/recorder/button-recorder.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "system.h"
24#include "button.h"
25#include "backlight.h"
26#include "adc.h"
27
28/*
29 Recorder hardware button hookup
30 ===============================
31
32 F1, F2, F3, UP: connected to AN4 through a resistor network
33 DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5
34
35 The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed
36
37 ON: PB8, low active
38 OFF: PB4, low active
39*/
40
41void button_init_device(void)
42{
43 /* Set PB4 and PB8 as input pins */
44 PBCR1 &= 0xfffc; /* PB8MD = 00 */
45 PBCR2 &= 0xfcff; /* PB4MD = 00 */
46 PBIOR &= ~0x0110; /* Inputs */
47}
48
49int button_read_device(void)
50{
51 int btn = BUTTON_NONE;
52 int data;
53 static int off_button_count = 0;
54
55 /* check F1..F3 and UP */
56 data = adc_read(ADC_BUTTON_ROW1);
57 if (data >= 250)
58 {
59 if (data >= 700)
60 if (data >= 900)
61 btn = BUTTON_F3;
62 else
63 btn = BUTTON_UP;
64 else
65 if (data >= 500)
66 btn = BUTTON_F2;
67 else
68 btn = BUTTON_F1;
69 }
70
71 /* Some units have mushy keypads, so pressing UP also activates
72 the Left/Right buttons. Let's combat that by skipping the AN5
73 checks when UP is pressed. */
74 if(!(btn & BUTTON_UP))
75 {
76 /* check DOWN, PLAY, LEFT, RIGHT */
77 data = adc_read(ADC_BUTTON_ROW2);
78 if (data >= 250)
79 {
80 if (data >= 700)
81 if (data >= 900)
82 btn |= BUTTON_DOWN;
83 else
84 btn |= BUTTON_PLAY;
85 else
86 if (data >= 500)
87 btn |= BUTTON_LEFT;
88 else
89 btn |= BUTTON_RIGHT;
90 }
91 }
92
93 /* check port B pins for ON and OFF */
94 data = PBDR;
95 if ((data & 0x0100) == 0)
96 btn |= BUTTON_ON;
97
98 if ((data & 0x0010) == 0)
99 {
100 /* When the batteries are low, the low-battery shutdown logic causes
101 * spurious OFF events due to voltage fluctuation on some units.
102 * Only accept OFF when read several times in sequence. */
103 if (++off_button_count > 3)
104 btn |= BUTTON_OFF;
105 }
106 else
107 off_button_count = 0;
108
109 return btn;
110}
diff --git a/firmware/target/sh/archos/recorder/button-target.h b/firmware/target/sh/archos/recorder/button-target.h
deleted file mode 100644
index f387fafe10..0000000000
--- a/firmware/target/sh/archos/recorder/button-target.h
+++ /dev/null
@@ -1,59 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _BUTTON_TARGET_H_
23#define _BUTTON_TARGET_H_
24
25#define HAS_SERIAL_REMOTE
26
27 /* Main unit's buttons */
28#define BUTTON_ON 0x00000001
29#define BUTTON_OFF 0x00000002
30
31#define BUTTON_LEFT 0x00000004
32#define BUTTON_RIGHT 0x00000008
33#define BUTTON_UP 0x00000010
34#define BUTTON_DOWN 0x00000020
35
36#define BUTTON_PLAY 0x00000040
37
38#define BUTTON_F1 0x00000080
39#define BUTTON_F2 0x00000100
40#define BUTTON_F3 0x00000200
41
42#define BUTTON_MAIN (BUTTON_ON|BUTTON_OFF|BUTTON_LEFT|BUTTON_RIGHT\
43 |BUTTON_UP|BUTTON_DOWN|BUTTON_PLAY\
44 |BUTTON_F1|BUTTON_F2|BUTTON_F3)
45
46 /* Remote control's buttons */
47#define BUTTON_RC_PLAY 0x00100000
48#define BUTTON_RC_STOP 0x00080000
49
50#define BUTTON_RC_LEFT 0x00040000
51#define BUTTON_RC_RIGHT 0x00020000
52#define BUTTON_RC_VOL_UP 0x00010000
53#define BUTTON_RC_VOL_DOWN 0x00008000
54
55#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
56 |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
57 |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
58
59#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/sh/archos/recorder/power-recorder.c b/firmware/target/sh/archos/recorder/power-recorder.c
deleted file mode 100644
index 48cfdc1e17..0000000000
--- a/firmware/target/sh/archos/recorder/power-recorder.c
+++ /dev/null
@@ -1,107 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23#include <stdbool.h>
24#include "adc.h"
25#include "kernel.h"
26#include "system.h"
27#include "power.h"
28#include "powermgmt-target.h"
29#include "usb.h"
30
31static bool charger_on;
32
33void power_init(void)
34{
35 PBCR2 &= ~0x0c00; /* GPIO for PB5 */
36 or_b(0x20, &PBIORL); /* Set charging control bit to output */
37 charger_enable(false); /* Default to charger OFF */
38}
39
40unsigned int power_input_status(void)
41{
42 /* Recorder */
43 return (adc_read(ADC_EXT_POWER) > 0x100) ?
44 POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
45}
46
47void charger_enable(bool on)
48{
49 if(on)
50 {
51 and_b(~0x20, &PBDRL);
52 }
53 else
54 {
55 or_b(0x20, &PBDRL);
56 }
57
58 charger_on = on;
59}
60
61bool charger_enabled(void)
62{
63 return charger_on;
64}
65
66void ide_power_enable(bool on)
67{
68 bool touched = false;
69
70 if(on)
71 {
72 or_b(0x20, &PADRL);
73 touched = true;
74 }
75#ifdef HAVE_ATA_POWER_OFF
76 if(!on)
77 {
78 and_b(~0x20, &PADRL);
79 touched = true;
80 }
81#endif /* HAVE_ATA_POWER_OFF */
82
83/* late port preparation, else problems with read/modify/write
84 of other bits on same port, while input and floating high */
85 if (touched)
86 {
87 or_b(0x20, &PAIORL); /* PA5 is an output */
88 PACR2 &= 0xFBFF; /* GPIO for PA5 */
89 }
90}
91
92
93bool ide_powered(void)
94{
95 if ((PACR2 & 0x0400) || !(PAIORL & 0x20)) /* not configured for output */
96 return true; /* would be floating high, disk on */
97 else
98 return (PADRL & 0x20) != 0;
99}
100
101void power_off(void)
102{
103 disable_irq();
104 and_b(~0x10, &PBDRL);
105 or_b(0x10, &PBIORL);
106 while(1);
107}
diff --git a/firmware/target/sh/archos/recorder/powermgmt-recorder.c b/firmware/target/sh/archos/recorder/powermgmt-recorder.c
deleted file mode 100644
index ca6067a4cc..0000000000
--- a/firmware/target/sh/archos/recorder/powermgmt-recorder.c
+++ /dev/null
@@ -1,501 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
11 * Revisions copyright (C) 2005 by Gerald Van Baren
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "config.h"
23#include "system.h"
24#include <stdio.h>
25#include "debug.h"
26#include "storage.h"
27#include "adc.h"
28#include "power.h"
29#include "powermgmt.h"
30
31const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
32{
33 4750
34};
35
36const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
37{
38 4400
39};
40
41/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
42const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
43{
44 /* original values were taken directly after charging, but it should show
45 100% after turning off the device for some hours, too */
46 { 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 }
47 /* orig. values: ...,5280,5600 */
48};
49
50/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
51const unsigned short percent_to_volt_charge[11] =
52{
53 /* values guessed, see
54 http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone
55 measures voltages over a charging cycle */
56 4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */
57};
58
59#define BATTERY_SCALE_FACTOR 6620
60/* full-scale ADC readout (2^10) in millivolt */
61
62/* Returns battery voltage from ADC [millivolts] */
63int _battery_voltage(void)
64{
65 return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
66}
67
68void powermgmt_init_target(void)
69{
70}
71
72/** Charger control **/
73#ifdef CHARGING_DEBUG_FILE
74#include "file.h"
75#define DEBUG_FILE_NAME "/powermgmt.csv"
76#define DEBUG_MESSAGE_LEN 133
77static char debug_message[DEBUG_MESSAGE_LEN];
78static int fd = -1; /* write debug information to this file */
79static int wrcount = 0;
80#endif /* CHARGING_DEBUG_FILE */
81
82/*
83 * For a complete description of the charging algorithm read
84 * docs/CHARGING_ALGORITHM.
85 */
86int long_delta; /* long term delta battery voltage */
87int short_delta; /* short term delta battery voltage */
88static bool disk_activity_last_cycle = false; /* flag set to aid charger time
89 * calculation */
90char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
91 debug menu */
92 /* percentage at which charging
93 starts */
94int powermgmt_last_cycle_startstop_min = 0; /* how many minutes ago was the
95 charging started or
96 stopped? */
97int powermgmt_last_cycle_level = 0; /* which level had the
98 batteries at this time? */
99int trickle_sec = 0; /* how many seconds should the
100 charger be enabled per
101 minute for trickle
102 charging? */
103int pid_p = 0; /* PID proportional term */
104int pid_i = 0; /* PID integral term */
105
106static unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle
107 * voltage level */
108static int charge_max_time_idle = 0; /* max. charging duration, calculated at
109 * beginning of charging */
110static int charge_max_time_now = 0; /* max. charging duration including
111 * hdd activity */
112static int minutes_disk_activity = 0; /* count minutes of hdd use during
113 * charging */
114static int last_disk_activity = CHARGE_END_LONGD + 1; /* last hdd use x mins ago */
115
116#ifdef CHARGING_DEBUG_FILE
117static void debug_file_close(void)
118{
119 if (fd >= 0) {
120 close(fd);
121 fd = -1;
122 }
123}
124
125static void debug_file_log(void)
126{
127 if (usb_inserted()) {
128 /* It is probably too late to close the file but we can try... */
129 debug_file_close();
130 }
131 else if (fd < 0) {
132 fd = open(DEBUG_FILE_NAME, O_WRONLY | O_APPEND | O_CREAT, 0666);
133
134 if (fd >= 0) {
135 snprintf(debug_message, DEBUG_MESSAGE_LEN,
136 "cycle_min, bat_millivolts, bat_percent, chgr_state"
137 " ,charge_state, pid_p, pid_i, trickle_sec\n");
138 write(fd, debug_message, strlen(debug_message));
139 wrcount = 99; /* force a flush */
140 }
141 }
142 else {
143 snprintf(debug_message, DEBUG_MESSAGE_LEN,
144 "%d, %d, %d, %d, %d, %d, %d, %d\n",
145 powermgmt_last_cycle_startstop_min, battery_voltage(),
146 battery_level(), charger_input_state, charge_state,
147 pid_p, pid_i, trickle_sec);
148 write(fd, debug_message, strlen(debug_message));
149 wrcount++;
150 }
151}
152
153static void debug_file_sync(void)
154{
155 /*
156 * If we have a lot of pending writes or if the disk is spining,
157 * fsync the debug log file.
158 */
159 if (wrcount > 10 || (wrcount > 0 && storage_disk_is_active())) {
160 if (fd >= 0)
161 fsync(fd);
162
163 wrcount = 0;
164 }
165}
166#else /* !CHARGING_DEBUG_FILE */
167#define debug_file_close()
168#define debug_file_log()
169#define debug_file_sync()
170#endif /* CHARGING_DEBUG_FILE */
171
172/*
173 * Do tasks that should be done every step.
174 */
175static void do_frequent_tasks(void)
176{
177 if (storage_disk_is_active()) {
178 /* flag hdd use for charging calculation */
179 disk_activity_last_cycle = true;
180 }
181
182 debug_file_sync();
183}
184
185/*
186 * The charger was just plugged in. If the battery level is
187 * nearly charged, just trickle. If the battery is low, start
188 * a full charge cycle. If the battery level is in between,
189 * top-off and then trickle.
190 */
191static void charger_plugged(void)
192{
193 int battery_percent = battery_level();
194
195 pid_p = 0;
196 pid_i = 0;
197 powermgmt_last_cycle_level = battery_percent;
198 powermgmt_last_cycle_startstop_min = 0;
199
200 snprintf(power_message, POWER_MESSAGE_LEN, "Charger plugged in");
201
202 if (battery_percent > START_TOPOFF_CHG) {
203
204 if (battery_percent >= START_TRICKLE_CHG) {
205 charge_state = TRICKLE;
206 target_voltage = TRICKLE_VOLTAGE;
207 }
208 else {
209 charge_state = TOPOFF;
210 target_voltage = TOPOFF_VOLTAGE;
211 }
212 }
213 else {
214 /*
215 * Start the charger full strength
216 */
217 int i = CHARGE_MAX_MIN_1500 * get_battery_capacity() / 1500;
218 charge_max_time_idle = i * (100 + 35 - battery_percent) / 100;
219
220 if (charge_max_time_idle > i)
221 charge_max_time_idle = i;
222
223 charge_max_time_now = charge_max_time_idle;
224
225 snprintf(power_message, POWER_MESSAGE_LEN,
226 "ChgAt %d%% max %dm", battery_percent,
227 charge_max_time_now);
228
229 /*
230 * Enable the charger after the max time calc is done,
231 * because battery_level depends on if the charger is
232 * on.
233 */
234 DEBUGF("power: charger inserted and battery"
235 " not full, charging\n");
236 trickle_sec = 60;
237 long_delta = short_delta = 999999;
238 charge_state = CHARGING;
239 }
240}
241
242/*
243 * The charger was just unplugged.
244 */
245static void charger_unplugged(void)
246{
247 DEBUGF("power: charger disconnected, disabling\n");
248
249 charger_enable(false);
250 powermgmt_last_cycle_level = battery_level();
251 powermgmt_last_cycle_startstop_min = 0;
252 trickle_sec = 0;
253 pid_p = 0;
254 pid_i = 0;
255 charge_state = DISCHARGING;
256 snprintf(power_message, POWER_MESSAGE_LEN, "Charger: discharge");
257}
258
259static void charging_step(void)
260{
261 int i;
262
263 /* alter charge time max length with extra disk use */
264 if (disk_activity_last_cycle) {
265 minutes_disk_activity++;
266 charge_max_time_now = charge_max_time_idle +
267 minutes_disk_activity*2 / 5;
268 disk_activity_last_cycle = false;
269 last_disk_activity = 0;
270 }
271 else {
272 last_disk_activity++;
273 }
274
275 /*
276 * Check the delta voltage over the last X minutes so we can do
277 * our end-of-charge logic based on the battery level change
278 * (no longer use minimum time as logic for charge end has 50
279 * minutes minimum charge built in).
280 */
281 if (powermgmt_last_cycle_startstop_min > CHARGE_END_SHORTD) {
282 short_delta = power_history[0] -
283 power_history[CHARGE_END_SHORTD - 1];
284 }
285
286 if (powermgmt_last_cycle_startstop_min > CHARGE_END_LONGD) {
287 /*
288 * Scan the history: the points where measurement is taken need to
289 * be fairly static. Check prior to short delta 'area'. Also only
290 * check first and last 10 cycles (delta in middle OK).
291 */
292 long_delta = power_history[0] -
293 power_history[CHARGE_END_LONGD - 1];
294
295 for (i = CHARGE_END_SHORTD; i < CHARGE_END_SHORTD + 10; i++)
296 {
297 if ((power_history[i] - power_history[i+1]) > 50 ||
298 (power_history[i] - power_history[i+1]) < -50) {
299 long_delta = 777777;
300 break;
301 }
302 }
303
304 for (i = CHARGE_END_LONGD - 11; i < CHARGE_END_LONGD - 1 ; i++)
305 {
306 if ((power_history[i] - power_history[i+1]) > 50 ||
307 (power_history[i] - power_history[i+1]) < -50) {
308 long_delta = 888888;
309 break;
310 }
311 }
312 }
313
314 snprintf(power_message, POWER_MESSAGE_LEN,
315 "Chg %dm, max %dm", powermgmt_last_cycle_startstop_min,
316 charge_max_time_now);
317
318 /*
319 * End of charge criteria (any qualify):
320 * 1) Charged a long time
321 * 2) DeltaV went negative for a short time ( & long delta static)
322 * 3) DeltaV was negative over a longer period (no disk use only)
323 *
324 * Note: short_delta and long_delta are millivolts
325 */
326 if (powermgmt_last_cycle_startstop_min >= charge_max_time_now ||
327 (short_delta <= -50 && long_delta < 50) ||
328 (long_delta < -20 && last_disk_activity > CHARGE_END_LONGD)) {
329
330 int battery_percent = battery_level();
331
332 if (powermgmt_last_cycle_startstop_min > charge_max_time_now) {
333 DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, "
334 "enough!\n");
335 /*
336 * Have charged too long and deltaV detection did not
337 * work!
338 */
339 snprintf(power_message, POWER_MESSAGE_LEN,
340 "Chg tmout %d min", charge_max_time_now);
341 /*
342 * Switch to trickle charging. We skip the top-off
343 * since we've effectively done the top-off operation
344 * already since we charged for the maximum full
345 * charge time.
346 */
347 powermgmt_last_cycle_level = battery_percent;
348 powermgmt_last_cycle_startstop_min = 0;
349 charge_state = TRICKLE;
350
351 /*
352 * Set trickle charge target to a relative voltage instead
353 * of an arbitrary value - the fully charged voltage may
354 * vary according to ambient temp, battery condition etc.
355 * Trickle target is -0.15v from full voltage acheived.
356 * Topup target is -0.05v from full voltage.
357 */
358 target_voltage = power_history[0] - 150;
359
360 }
361 else {
362 if(short_delta <= -5) {
363 DEBUGF("power: short-term negative"
364 " delta, enough!\n");
365 snprintf(power_message, POWER_MESSAGE_LEN,
366 "end negd %d %dmin", short_delta,
367 powermgmt_last_cycle_startstop_min);
368 target_voltage = power_history[CHARGE_END_SHORTD - 1] - 50;
369 }
370 else {
371 DEBUGF("power: long-term small "
372 "positive delta, enough!\n");
373 snprintf(power_message, POWER_MESSAGE_LEN,
374 "end lowd %d %dmin", long_delta,
375 powermgmt_last_cycle_startstop_min);
376 target_voltage = power_history[CHARGE_END_LONGD - 1] - 50;
377 }
378
379 /*
380 * Switch to top-off charging.
381 */
382 powermgmt_last_cycle_level = battery_percent;
383 powermgmt_last_cycle_startstop_min = 0;
384 charge_state = TOPOFF;
385 }
386 }
387}
388
389static void topoff_trickle_step(void)
390{
391 unsigned int millivolts;
392
393 /*
394 *Time to switch from topoff to trickle?
395 */
396 if (charge_state == TOPOFF &&
397 powermgmt_last_cycle_startstop_min > TOPOFF_MAX_MIN) {
398
399 powermgmt_last_cycle_level = battery_level();
400 powermgmt_last_cycle_startstop_min = 0;
401 charge_state = TRICKLE;
402 target_voltage = target_voltage - 100;
403 }
404 /*
405 * Adjust trickle charge time (proportional and integral terms).
406 * Note: I considered setting the level higher if the USB is
407 * plugged in, but it doesn't appear to be necessary and will
408 * generate more heat [gvb].
409 */
410 millivolts = battery_voltage();
411
412 pid_p = ((signed)target_voltage - (signed)millivolts) / 5;
413 if (pid_p <= PID_DEADZONE && pid_p >= -PID_DEADZONE)
414 pid_p = 0;
415
416 if ((unsigned)millivolts < target_voltage) {
417 if (pid_i < 60)
418 pid_i++; /* limit so it doesn't "wind up" */
419 }
420 else {
421 if (pid_i > 0)
422 pid_i--; /* limit so it doesn't "wind up" */
423 }
424
425 trickle_sec = pid_p + pid_i;
426
427 if (trickle_sec > 60)
428 trickle_sec = 60;
429
430 if (trickle_sec < 0)
431 trickle_sec = 0;
432}
433
434void charging_algorithm_step(void)
435{
436 static int pwm_counter = 0; /* PWM total cycle in steps */
437 static int pwm_duty = 0; /* PWM duty cycle in steps */
438
439 switch (charger_input_state)
440 {
441 case CHARGER_PLUGGED:
442 charger_plugged();
443 break;
444
445 case CHARGER_UNPLUGGED:
446 charger_unplugged();
447 break;
448
449 case CHARGER:
450 case NO_CHARGER:
451 do_frequent_tasks();
452
453 if (pwm_counter > 0) {
454 if (pwm_duty > 0 && --pwm_duty <= 0)
455 charger_enable(false); /* Duty cycle expired */
456
457 if (--pwm_counter > 0)
458 return;
459
460 /* PWM cycle is complete */
461 powermgmt_last_cycle_startstop_min++;
462 debug_file_log();
463 }
464 break;
465 }
466
467 switch (charge_state)
468 {
469 case CHARGING:
470 charging_step();
471 break;
472
473 case TOPOFF:
474 case TRICKLE:
475 topoff_trickle_step();
476 break;
477
478 case DISCHARGING:
479 default:
480 break;
481 }
482
483 /* If 100%, ensure pwm_on never expires and briefly disables the
484 * charger. */
485 pwm_duty = (trickle_sec < 60) ? trickle_sec*2 : 0;
486 pwm_counter = 60*2;
487 charger_enable(trickle_sec > 0);
488}
489
490void charging_algorithm_close(void)
491{
492#ifdef CHARGING_DEBUG_FILE
493 debug_file_close();
494#endif /* CHARGING_DEBUG_FILE */
495}
496
497/* Returns true if the unit is charging the batteries. */
498bool charging_state(void)
499{
500 return charge_state == CHARGING;
501}
diff --git a/firmware/target/sh/archos/recorder/powermgmt-target.h b/firmware/target/sh/archos/recorder/powermgmt-target.h
deleted file mode 100644
index 6b68d05bd4..0000000000
--- a/firmware/target/sh/archos/recorder/powermgmt-target.h
+++ /dev/null
@@ -1,89 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
11 * Revisions copyright (C) 2005 by Gerald Van Baren
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#ifndef POWERMGMT_TARGET_H
23#define POWERMGMT_TARGET_H
24
25/*
26 * Define CHARGING_DEBUG_FILE to create a csv (spreadsheet) with battery
27 * information in it (one sample per minute/connect/disconnect).
28 *
29 * This is only for very low level debug.
30 */
31#undef CHARGING_DEBUG_FILE
32
33
34/* stop when N minutes have passed with avg delta being < -0.05 V */
35#define CHARGE_END_SHORTD 6
36/* stop when N minutes have passed with avg delta being < -0.02 V */
37#define CHARGE_END_LONGD 50
38
39/* Battery % to start at top-off */
40#define START_TOPOFF_CHG 85
41/* Battery % to start at trickle */
42#define START_TRICKLE_CHG 95
43/* power thread status message */
44#define POWER_MESSAGE_LEN 32
45/* minutes: maximum charging time for 1500 mAh batteries
46 * actual max time depends also on BATTERY_CAPACITY! */
47#define CHARGE_MAX_MIN_1500 450
48/* minutes: minimum charging time */
49#define CHARGE_MIN_MIN 10
50/* After charging, go to top off charge. How long should top off charge be? */
51#define TOPOFF_MAX_MIN 90
52/* which voltage is best? (millivolts) */
53#define TOPOFF_VOLTAGE 5650
54/* After top off charge, go to trickle harge. How long should trickle
55 * charge be? */
56#define TRICKLE_MAX_MIN 720 /* 12 hrs */
57/* which voltage is best? (millivolts) */
58#define TRICKLE_VOLTAGE 5450
59/* initial trickle_sec for topoff */
60#define START_TOPOFF_SEC 25
61/* initial trickle_sec for trickle */
62#define START_TRICKLE_SEC 15
63
64#define PID_DEADZONE 4 /* PID proportional deadzone */
65
66extern char power_message[POWER_MESSAGE_LEN];
67
68extern int long_delta; /* long term delta battery voltage */
69extern int short_delta; /* short term delta battery voltage */
70
71extern int powermgmt_last_cycle_startstop_min; /* how many minutes ago was
72 the charging started or
73 stopped? */
74extern int powermgmt_last_cycle_level; /* which level had the batteries
75 at this time? */
76
77extern int pid_p; /* PID proportional term */
78extern int pid_i; /* PID integral term */
79extern int trickle_sec; /* how many seconds should the
80 charger be enabled per
81 minute for trickle
82 charging? */
83void charger_enable(bool on);
84bool charger_enabled(void);
85
86/* Battery filter lengths in samples */
87#define BATT_AVE_SAMPLES 32
88
89#endif /* POWERMGMT_TARGET_H */
diff --git a/firmware/target/sh/archos/recorder/usb-recorder.c b/firmware/target/sh/archos/recorder/usb-recorder.c
deleted file mode 100644
index f8b462b802..0000000000
--- a/firmware/target/sh/archos/recorder/usb-recorder.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include <stdbool.h>
23#include "adc.h"
24#include "cpu.h"
25#include "hwcompat.h"
26#include "system.h"
27#include "usb.h"
28
29int usb_detect(void)
30{
31 return (adc_read(ADC_USB_POWER) > 500) ? USB_INSERTED : USB_EXTRACTED;
32}
33
34void usb_enable(bool on)
35{
36 if(HW_MASK & USB_ACTIVE_HIGH)
37 on = !on;
38
39 if(on)
40 and_b(~0x04, &PADRH); /* enable USB */
41 else
42 or_b(0x04, &PADRH);
43}
44
45void usb_init_device(void)
46{
47 usb_enable(false);
48 or_b(0x04, &PAIORH);
49}