diff options
-rw-r--r-- | firmware/backlight.c | 213 | ||||
-rw-r--r-- | firmware/system.c | 7 |
2 files changed, 217 insertions, 3 deletions
diff --git a/firmware/backlight.c b/firmware/backlight.c index e006d3aeb5..84d3f1a31e 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c | |||
@@ -59,6 +59,218 @@ static int remote_backlight_timer; | |||
59 | static unsigned int remote_backlight_timeout = 5; | 59 | static unsigned int remote_backlight_timeout = 5; |
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | #if CONFIG_BACKLIGHT == BL_IRIVER | ||
63 | #define BL_PWM_COUNT 100 | ||
64 | /* Cycle interval in ms */ | ||
65 | #define BL_PWM_INTERVAL 5000 | ||
66 | #define BL_PWM_INTERVAL_IDLE 500000 | ||
67 | #define BL_DIM_SPEED 4 | ||
68 | #define __backlight_on __backlight_fade_in | ||
69 | #define __backlight_off __backlight_fade_out | ||
70 | |||
71 | #define DIM_STATE_START 0 | ||
72 | #define DIM_STATE_MAIN 1 | ||
73 | #define DIM_STATE_REMOTE 2 | ||
74 | |||
75 | static bool bl_timer_active = false; | ||
76 | static int bl_dim_current = BL_PWM_COUNT; | ||
77 | static int bl_dim_target = BL_PWM_COUNT; | ||
78 | static int bl_pwm_counter = 0; | ||
79 | static volatile int bl_cycle_counter = 0; | ||
80 | |||
81 | /* Unfortunately we can't dim H1xx remote lcd :/ */ | ||
82 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
83 | #define lcd_remote_backlight_on __backlight_fade_remote_in | ||
84 | #define lcd_remote_backlight_off __backlight_fade_remote_out | ||
85 | static int bl_dim_remote_current = BL_PWM_COUNT; | ||
86 | static int bl_dim_remote_target = BL_PWM_COUNT; | ||
87 | static int bl_pwm_remote_counter = 0; | ||
88 | static bool bl_dim_next_interval; | ||
89 | #endif | ||
90 | |||
91 | static int bl_dim_state = 0; | ||
92 | |||
93 | void backlight_start_timer(void) | ||
94 | { | ||
95 | unsigned int count; | ||
96 | |||
97 | if (bl_timer_active) | ||
98 | return ; | ||
99 | |||
100 | count = 1; | ||
101 | bl_timer_active = true; | ||
102 | |||
103 | /* We are using timer 1 */ | ||
104 | TRR1 = count; /* The reference count */ | ||
105 | TCN1 = 0; /* reset the timer */ | ||
106 | TMR1 = 0x011d; /* prescaler=2, restart, CLK/16, enabled */ | ||
107 | |||
108 | TER1 = 0xff; /* Clear all events */ | ||
109 | |||
110 | /* ICR2 (Timer2) */ | ||
111 | ICR0 = (ICR0 & 0xffff00ff) | 0x00009000; /* Interrupt on level 4.0 */ | ||
112 | IMR &= ~(1<<10); | ||
113 | } | ||
114 | |||
115 | void TIMER1(void) __attribute__ ((interrupt_handler)); | ||
116 | void TIMER1(void) | ||
117 | { | ||
118 | int timer_period; | ||
119 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
120 | int new_timer_period; | ||
121 | #endif | ||
122 | |||
123 | timer_period = FREQ/20000 * BL_PWM_INTERVAL / 100 / 32; | ||
124 | switch (bl_dim_state) { | ||
125 | /* New cycle */ | ||
126 | case DIM_STATE_START: | ||
127 | bl_pwm_counter = 0; | ||
128 | bl_cycle_counter++; | ||
129 | |||
130 | if (bl_dim_current > 0 && bl_dim_current < BL_PWM_COUNT) { | ||
131 | GPIO1_OUT &= ~0x00020000; | ||
132 | bl_pwm_counter = bl_dim_current; | ||
133 | timer_period = timer_period * bl_pwm_counter / BL_PWM_COUNT; | ||
134 | bl_dim_state = DIM_STATE_MAIN; | ||
135 | } else { | ||
136 | if (bl_dim_current) | ||
137 | GPIO1_OUT &= ~0x00020000; | ||
138 | else | ||
139 | GPIO1_OUT |= 0x00020000; | ||
140 | } | ||
141 | |||
142 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
143 | bl_dim_next_interval = 0; | ||
144 | bl_pwm_remote_counter = 0; | ||
145 | if (bl_dim_remote_current > 0 && | ||
146 | bl_dim_remote_current < BL_PWM_COUNT) { | ||
147 | GPIO_OUT &= ~0x00000800; | ||
148 | bl_pwm_remote_counter = bl_dim_remote_current; | ||
149 | if (bl_dim_state == DIM_STATE_START) { | ||
150 | timer_period = timer_period * bl_pwm_remote_counter | ||
151 | / BL_PWM_COUNT; | ||
152 | bl_dim_state = DIM_STATE_REMOTE; | ||
153 | break ; | ||
154 | } | ||
155 | |||
156 | new_timer_period = timer_period * bl_pwm_remote_counter | ||
157 | / BL_PWM_COUNT; | ||
158 | if (new_timer_period < timer_period) { | ||
159 | bl_dim_next_interval = timer_period - new_timer_period; | ||
160 | timer_period = new_timer_period; | ||
161 | bl_dim_state = DIM_STATE_REMOTE; | ||
162 | } else { | ||
163 | bl_dim_next_interval = new_timer_period - timer_period; | ||
164 | } | ||
165 | } else { | ||
166 | if (bl_dim_remote_current) | ||
167 | GPIO_OUT &= ~0x00000800; | ||
168 | else | ||
169 | GPIO_OUT |= 0x00000800; | ||
170 | } | ||
171 | #endif | ||
172 | break ; | ||
173 | |||
174 | /* Dim main screen */ | ||
175 | case DIM_STATE_MAIN: | ||
176 | GPIO1_OUT |= 0x00020000; | ||
177 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
178 | if (bl_dim_next_interval) { | ||
179 | timer_period = bl_dim_next_interval; | ||
180 | bl_dim_next_interval = 0; | ||
181 | bl_dim_state = DIM_STATE_REMOTE; | ||
182 | break ; | ||
183 | } | ||
184 | #endif | ||
185 | bl_dim_state = DIM_STATE_START; | ||
186 | timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_counter) / BL_PWM_COUNT; | ||
187 | break ; | ||
188 | |||
189 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
190 | /* Dim remote lcd */ | ||
191 | case DIM_STATE_REMOTE: | ||
192 | GPIO_OUT |= 0x00000800; | ||
193 | if (bl_dim_next_interval) { | ||
194 | timer_period = bl_dim_next_interval; | ||
195 | bl_dim_next_interval = 0; | ||
196 | bl_dim_state = DIM_STATE_MAIN; | ||
197 | break ; | ||
198 | } | ||
199 | |||
200 | bl_dim_state = DIM_STATE_START; | ||
201 | timer_period = timer_period * (BL_PWM_COUNT - bl_pwm_remote_counter) / BL_PWM_COUNT; | ||
202 | break ; | ||
203 | #endif | ||
204 | } | ||
205 | |||
206 | if (bl_cycle_counter >= BL_DIM_SPEED) { | ||
207 | bool idle = true; | ||
208 | if (bl_dim_target > bl_dim_current) { | ||
209 | bl_dim_current++; | ||
210 | idle = false; | ||
211 | } | ||
212 | else if (bl_dim_target < bl_dim_current) { | ||
213 | bl_dim_current--; | ||
214 | idle = false; | ||
215 | } | ||
216 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
217 | if (bl_dim_remote_target > bl_dim_remote_current) { | ||
218 | bl_dim_remote_current++; | ||
219 | idle = false; | ||
220 | } | ||
221 | else if (bl_dim_remote_target < bl_dim_remote_current) { | ||
222 | bl_dim_remote_current--; | ||
223 | idle = false; | ||
224 | } | ||
225 | #endif | ||
226 | bl_cycle_counter = 0; | ||
227 | |||
228 | /* Save CPU & battery when idle, stop timer */ | ||
229 | if (idle) { | ||
230 | bl_timer_active = false; | ||
231 | TMR1 = 0; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | TRR1 = timer_period; | ||
236 | TCN1 = 0; | ||
237 | TER1 = 0xff; /* Clear all events */ | ||
238 | } | ||
239 | |||
240 | static void __backlight_dim(int value) | ||
241 | { | ||
242 | bl_dim_target = value; | ||
243 | backlight_start_timer(); | ||
244 | } | ||
245 | |||
246 | static void __backlight_fade_in(void) | ||
247 | { | ||
248 | __backlight_dim(BL_PWM_COUNT); | ||
249 | } | ||
250 | |||
251 | static void __backlight_fade_out(void) | ||
252 | { | ||
253 | __backlight_dim(0); | ||
254 | } | ||
255 | |||
256 | #ifdef HAVE_REMOTE_LCD_DIMMABLE | ||
257 | static void __backlight_dim_remote(int value) | ||
258 | { | ||
259 | bl_dim_remote_target = value; | ||
260 | } | ||
261 | |||
262 | static void __backlight_fade_remote_in(void) | ||
263 | { | ||
264 | __backlight_dim_remote(BL_PWM_COUNT); | ||
265 | } | ||
266 | |||
267 | static void __backlight_fade_remote_out(void) | ||
268 | { | ||
269 | __backlight_dim_remote(0); | ||
270 | } | ||
271 | #endif | ||
272 | |||
273 | #else | ||
62 | static void __backlight_off(void) | 274 | static void __backlight_off(void) |
63 | { | 275 | { |
64 | #if CONFIG_BACKLIGHT == BL_IRIVER | 276 | #if CONFIG_BACKLIGHT == BL_IRIVER |
@@ -91,6 +303,7 @@ static void __backlight_on(void) | |||
91 | P1 |= 0x10; | 303 | P1 |= 0x10; |
92 | #endif | 304 | #endif |
93 | } | 305 | } |
306 | #endif | ||
94 | 307 | ||
95 | void backlight_thread(void) | 308 | void backlight_thread(void) |
96 | { | 309 | { |
diff --git a/firmware/system.c b/firmware/system.c index d095e1574a..66bd90f71b 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -432,12 +432,13 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = | |||
432 | UIE,UIE,UIE,UIE,UIE,UIE, | 432 | UIE,UIE,UIE,UIE,UIE,UIE, |
433 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, | 433 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, |
434 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, | 434 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, |
435 | UIE,UIE,UIE,TIMER0,UIE,UIE,UIE,UIE, | 435 | UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE, |
436 | 436 | /* lvl 3 lvl 4 */ | |
437 | |||
437 | TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, | 438 | TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, |
438 | TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, | 439 | TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, |
439 | 440 | ||
440 | SWT,UIE,TIMER1,I2C,UART1,UART2,DMA0,DMA1, | 441 | SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, |
441 | DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, | 442 | DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, |
442 | PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, | 443 | PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, |
443 | IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR, | 444 | IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR, |