00001 00006 /* 00007 * The contents of this file are subject to the Mozilla Public License 00008 * Version 1.0 (the "License"); you may not use this file except in 00009 * compliance with the License. You may obtain a copy of the License at 00010 * http://www.mozilla.org/MPL/ 00011 * 00012 * Software distributed under the License is distributed on an "AS IS" 00013 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 00014 * License for the specific language governing rights and limitations 00015 * under the License. 00016 * 00017 * The Original Code is legOS code, released October 17, 1999. 00018 * 00019 * The Initial Developer of the Original Code is Markus L. Noga. 00020 * Portions created by Markus L. Noga are Copyright (C) 1999 00021 * Markus L. Noga. All Rights Reserved. 00022 * 00023 * Contributor(s): Markus L. Noga <markus@noga.de> 00024 * David Van Wagner <davevw@alumni.cse.ucsc.edu> 00025 */ 00026 00027 /* 00028 * 2000.05.01 - Paolo Masetti <paolo.masetti@itlug.org> 00029 * 00030 * - Added battery indicator handler 00031 * 00032 * 2000.08.12 - Rossz Vámos-Wentworth <rossw@jps.net> 00033 * 00034 * - Added idle shutdown handler 00035 * 00036 */ 00037 00038 #include <config.h> 00039 00040 #ifdef CONF_TIME 00041 00042 #include <sys/time.h> 00043 #include <sys/h8.h> 00044 #include <sys/irq.h> 00045 #include <sys/dmotor.h> 00046 #include <sys/dsound.h> 00047 #include <sys/battery.h> 00048 #include <sys/critsec.h> 00049 #ifdef CONF_AUTOSHUTOFF 00050 #include <sys/timeout.h> 00051 #endif 00052 00054 // 00055 // Global Variables 00056 // 00058 00060 00063 volatile time_t sys_time; 00064 00066 // 00067 // Internal Variables 00068 // 00070 00071 #ifdef CONF_TM 00072 volatile unsigned char tm_timeslice; 00073 volatile unsigned char tm_current_slice; 00074 00075 void* tm_switcher_vector; 00076 #endif 00077 00078 00080 // 00081 // Functions 00082 // 00084 00086 00088 extern void clock_handler(void); 00089 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00090 __asm__("\n\ 00091 .text\n\ 00092 .align 1\n\ 00093 .global _clock_handler\n\ 00094 _clock_handler:\n\ 00095 mov.w #0x5a07,r6 ; reset wd timer to 6\n\ 00096 mov.w r6,@0xffa8\n\ 00097 \n\ 00098 mov.w @_sys_time+2,r6 ; lower 8 bits\n\ 00099 add.b #0x1,r6l ; inc lower 4 bits\n\ 00100 addx #0x0,r6h ; add carry to top 4 bits\n\ 00101 mov.w r6,@_sys_time+2\n\ 00102 bcc sys_nohigh ; if carry, inc upper 8 bits\n\ 00103 mov.w @_sys_time,r6 ; \n\ 00104 add.b #0x1,r6l ; inc lower 4 bits\n\ 00105 addx #0x0,r6h ; add carry to top 4 bits\n\ 00106 mov.w r6,@_sys_time\n\ 00107 sys_nohigh: \n\ 00108 rts\n\ 00109 "); 00110 #endif // DOXYGEN_SHOULD_SKIP_THIS 00111 00113 00117 extern void subsystem_handler(void); 00118 00120 00122 extern void task_switch_handler(void); 00123 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00124 __asm__("\n\ 00125 .text\n\ 00126 .align 1\n\ 00127 .global _subsystem_handler\n\ 00128 .global _task_switch_handler\n\ 00129 .global _systime_tm_return\n\ 00130 _subsystem_handler:\n\ 00131 ; r6 saved by ROM\n\ 00132 \n\ 00133 push r0 ; both motors & task\n\ 00134 ; switcher need this reg.\n\ 00135 " 00136 00137 #ifdef CONF_DSOUND 00138 "\n\ 00139 jsr _dsound_handler ; call sound handler\n\ 00140 " 00141 #endif // CONF_DSOUND 00142 00143 #ifdef CONF_LNP 00144 "\n\ 00145 mov.w @_lnp_timeout_counter,r6 ; check LNP timeout counter\n\ 00146 subs #0x1,r6\n\ 00147 mov.w r6,r6 ; subs doesn't change flags!\n\ 00148 bne sys_noreset\n\ 00149 \n\ 00150 jsr _lnp_integrity_reset\n\ 00151 mov.w @_lnp_timeout,r6 ; reset timeout\n\ 00152 \n\ 00153 sys_noreset:\n\ 00154 mov.w r6,@_lnp_timeout_counter\n\ 00155 " 00156 #endif // CONF_LNP 00157 00158 #ifdef CONF_DKEY 00159 "\n\ 00160 jsr _dkey_handler\n\ 00161 " 00162 #endif // CONF_DKEY 00163 00164 #ifndef CONF_TM 00165 #ifdef CONF_BATTERY_INDICATOR 00166 "\n\ 00167 mov.w @_battery_refresh_counter,r6\n\ 00168 subs #0x1,r6\n\ 00169 bne batt_norefresh\n\ 00170 \n\ 00171 jsr _battery_refresh\n\ 00172 mov.w @_battery_refresh_period,r6\n\ 00173 \n\ 00174 batt_norefresh:\n\ 00175 mov.w r6,@_battery_refresh_counter\n\ 00176 " 00177 #endif // CONF_BATTERY_INDICATOR 00178 #endif // CONF_TM 00179 00180 #ifdef CONF_AUTOSHUTOFF 00181 "\n\ 00182 mov.w @_auto_shutoff_counter,r6\n\ 00183 subs #0x1,r6\n\ 00184 bne auto_notshutoff\n\ 00185 \n\ 00186 jsr _autoshutoff_check\n\ 00187 mov.w @_auto_shutoff_period,r6\n\ 00188 \n\ 00189 auto_notshutoff:\n\ 00190 mov.w r6,@_auto_shutoff_counter\n\ 00191 " 00192 #endif // CONF_AUTOSHUTOFF 00193 00194 #ifdef CONF_VIS 00195 "\n\ 00196 mov.b @_vis_refresh_counter,r6l\n\ 00197 dec r6l\n\ 00198 bne vis_norefresh\n\ 00199 \n\ 00200 jsr _vis_handler\n\ 00201 mov.b @_vis_refresh_period,r6l\n\ 00202 \n\ 00203 vis_norefresh:\n\ 00204 mov.b r6l,@_vis_refresh_counter\n\ 00205 " 00206 #endif // CONF_VIS 00207 00208 #ifdef CONF_LCD_REFRESH 00209 "\n\ 00210 mov.b @_lcd_refresh_counter,r6l\n\ 00211 dec r6l\n\ 00212 bne lcd_norefresh\n\ 00213 \n\ 00214 jsr _lcd_refresh_next_byte\n\ 00215 mov.b @_lcd_refresh_period,r6l\n\ 00216 \n\ 00217 lcd_norefresh:\n\ 00218 mov.b r6l,@_lcd_refresh_counter\n\ 00219 " 00220 #endif // CONF_LCD_REFRESH 00221 "\n\ 00222 bclr #2,@0x91:8 ; reset compare B IRQ flag\n\ 00223 " 00224 #ifdef CONF_TM 00225 "\n\ 00226 pop r0 ; if fallthrough, pop r0\n\ 00227 _task_switch_handler:\n\ 00228 push r0 ; save r0\n\ 00229 \n\ 00230 mov.b @_tm_current_slice,r6l\n\ 00231 dec r6l\n\ 00232 bne sys_noswitch ; timeslice elapsed?\n\ 00233 \n\ 00234 mov.w @_kernel_critsec_count,r6 ; check critical section\n\ 00235 beq sys_switch ; ok to switch\n\ 00236 mov.b #1,r6l ; wait another tick\n\ 00237 jmp sys_noswitch ; don't switch\n\ 00238 \n\ 00239 sys_switch:\n\ 00240 mov.w @_tm_switcher_vector,r6\n\ 00241 jsr @r6 ; call task switcher\n\ 00242 \n\ 00243 _systime_tm_return:\n\ 00244 mov.b @_tm_timeslice,r6l ; new timeslice\n\ 00245 \n\ 00246 sys_noswitch:\n\ 00247 mov.b r6l,@_tm_current_slice\n\ 00248 " 00249 #endif // CONF_TM 00250 00251 #ifdef CONF_DMOTOR 00252 "\n\ 00253 jsr _dm_handler ; call motor driver\n\ 00254 " 00255 #endif // CONF_DMOTOR 00256 00257 "\n\ 00258 pop r0\n\ 00259 bclr #3,@0x91:8 ; reset compare A IRQ flag\n\ 00260 rts\n\ 00261 " 00262 ); 00263 #endif // DOXYGEN_SHOULD_SKIP_THIS 00264 00265 00267 00270 void systime_init(void) { 00271 systime_shutdown(); // shutdown hardware 00272 00273 sys_time=0l; // init timer 00274 00275 #ifdef CONF_TM 00276 tm_current_slice=tm_timeslice=TM_DEFAULT_SLICE; 00277 tm_switcher_vector=&rom_dummy_handler; // empty handler 00278 #endif 00279 00280 #ifdef CONF_DMOTOR 00281 dm_shutdown(); 00282 #endif 00283 00284 // configure 16-bit timer 00285 // compare B IRQ will fire after one msec 00286 // compare A IRQ will fire after another msec 00287 // counter is then reset 00288 // 00289 T_CSR = TCSR_RESET_ON_A; 00290 T_CR = TCR_CLOCK_32; 00291 T_OCR &= ~TOCR_OCRB; 00292 T_OCRA = 1000; 00293 T_OCR &= ~TOCR_OCRA; 00294 T_OCR |= TOCR_OCRB; 00295 T_OCRB = 500; 00296 00297 #if defined(CONF_TM) 00298 ocia_vector = &task_switch_handler; 00299 #else // CONF_TM 00300 ocia_vector = &subsystem_handler; 00301 #endif // CONF_TM 00302 ocib_vector = &subsystem_handler; 00303 T_IER |= (TIER_ENABLE_OCB | TIER_ENABLE_OCA); 00304 00305 nmi_vector = &clock_handler; 00306 WDT_CSR = WDT_CNT_PASSWORD | WDT_CNT_MSEC_64; // trigger every msec 00307 WDT_CSR = WDT_CSR_PASSWORD 00308 | WDT_CSR_CLOCK_64 00309 | WDT_CSR_WATCHDOG_NMI 00310 | WDT_CSR_ENABLE 00311 | WDT_CSR_MODE_WATCHDOG; 00312 } 00313 00315 00317 void systime_shutdown(void) { 00318 T_IER &= ~(TIER_ENABLE_OCA | TIER_ENABLE_OCB); // unhook compare A/B IRQs 00319 WDT_CSR &= ~WDT_CSR_ENABLE; // disable wd timer 00320 } 00321 00322 #ifdef CONF_TM 00323 00324 00326 void systime_set_switcher(void* switcher) { 00327 tm_switcher_vector=switcher; 00328 } 00329 00331 00333 void systime_set_timeslice(unsigned char slice) { 00334 if(slice>5) { // some minimum value 00335 tm_timeslice=slice; 00336 if(tm_current_slice>tm_timeslice) 00337 tm_current_slice=tm_timeslice; 00338 } 00339 } 00340 00341 #endif 00342 00344 00351 extern time_t get_system_up_time(void); 00352 __asm__("\n\ 00353 .text\n\ 00354 .align 1\n\ 00355 .global _get_system_up_time\n\ 00356 _get_system_up_time:\n\ 00357 push r2\n\ 00358 try_again:\n\ 00359 mov.w @_sys_time+2, r1\n\ 00360 mov.w @_sys_time, r0\n\ 00361 mov.w @_sys_time+2, r2\n\ 00362 cmp r2, r1\n\ 00363 bne try_again\n\ 00364 pop r2\n\ 00365 rts\n\ 00366 "); 00367 00368 #endif // CONF_TIME
brickOS is released under the
Mozilla Public License.
Original code copyright 1998-2002 by the authors. |