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 /*! \warning This is a 32 bit value which will overflow after 49.7 days 00061 of continuous operation. 00062 */ 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 /*! this is the system clock 00087 */ 00088 extern void clock_handler(void); 00089 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00090 __asm__(" 00091 .text 00092 .align 1 00093 .global _clock_handler 00094 _clock_handler: 00095 mov.w @_sys_time+2,r6 ; lower 8 bits 00096 add.b #0x1,r6l ; inc lower 4 bits 00097 addx #0x0,r6h ; add carry to top 4 bits 00098 mov.w r6,@_sys_time+2 00099 bcc sys_nohigh ; if carry, inc upper 8 bits 00100 mov.w @_sys_time,r6 ; 00101 add.b #0x1,r6l ; inc lower 4 bits 00102 addx #0x0,r6h ; add carry to top 4 bits 00103 mov.w r6,@_sys_time 00104 sys_nohigh: 00105 mov.w #0x5a06,r6 ; reset wd timer to 6 00106 mov.w r6,@0xa8 00107 rts 00108 "); 00109 #endif // DOXYGEN_SHOULD_SKIP_THIS 00110 00112 00116 extern void subsystem_handler(void); 00117 00119 00121 extern void task_switch_handler(void); 00122 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00123 __asm__(" 00124 .text 00125 .align 1 00126 .global _subsystem_handler 00127 .global _task_switch_handler 00128 .global _systime_tm_return 00129 _subsystem_handler: 00130 ; r6 saved by ROM 00131 00132 push r0 ; both motors & task 00133 ; switcher need this reg. 00134 " 00135 #ifdef CONF_DMOTOR 00136 " 00137 jsr _dm_handler ; call motor driver 00138 " 00139 #endif 00140 00141 #ifdef CONF_DSOUND 00142 " 00143 jsr _dsound_handler ; call sound handler 00144 " 00145 #endif 00146 00147 #ifdef CONF_LNP 00148 " 00149 mov.w @_lnp_timeout_counter,r6 ; check LNP timeout counter 00150 subs #0x1,r6 00151 mov.w r6,r6 ; subs doesn't change flags! 00152 bne sys_noreset 00153 00154 jsr _lnp_integrity_reset 00155 mov.w @_lnp_timeout,r6 ; reset timeout 00156 00157 sys_noreset: 00158 mov.w r6,@_lnp_timeout_counter 00159 " 00160 #endif 00161 00162 #ifdef CONF_DKEY 00163 " 00164 jsr _dkey_handler 00165 " 00166 #endif 00167 00168 #ifndef CONF_TM 00169 #ifdef CONF_BATTERY_INDICATOR 00170 " 00171 mov.w @_battery_refresh_counter,r6 00172 subs #0x1,r6 00173 bne batt_norefresh 00174 00175 jsr _battery_refresh 00176 mov.w @_battery_refresh_period,r6 00177 00178 batt_norefresh: 00179 mov.w r6,@_battery_refresh_counter 00180 " 00181 #endif 00182 #endif 00183 00184 #ifdef CONF_AUTOSHUTOFF 00185 " 00186 mov.w @_auto_shutoff_counter,r6 00187 subs #0x1,r6 00188 bne auto_notshutoff 00189 00190 jsr _autoshutoff_check 00191 mov.w @_auto_shutoff_period,r6 00192 00193 auto_notshutoff: 00194 mov.w r6,@_auto_shutoff_counter 00195 " 00196 #endif 00197 00198 #ifdef CONF_VIS 00199 " 00200 mov.b @_vis_refresh_counter,r6l 00201 dec r6l 00202 bne vis_norefresh 00203 00204 jsr _vis_handler 00205 mov.b @_vis_refresh_period,r6l 00206 00207 vis_norefresh: 00208 mov.b r6l,@_vis_refresh_counter 00209 " 00210 #endif 00211 00212 #ifdef CONF_LCD_REFRESH 00213 " 00214 mov.b @_lcd_refresh_counter,r6l 00215 dec r6l 00216 bne lcd_norefresh 00217 00218 jsr _lcd_refresh_next_byte 00219 mov.b @_lcd_refresh_period,r6l 00220 00221 lcd_norefresh: 00222 mov.b r6l,@_lcd_refresh_counter 00223 " 00224 #endif 00225 " 00226 bclr #2,@0x91:8 ; reset compare B IRQ flag 00227 " 00228 #ifdef CONF_TM 00229 " 00230 pop r0 ; if fallthrough, pop r0 00231 _task_switch_handler: 00232 push r0 ; save r0 00233 00234 mov.b @_tm_current_slice,r6l 00235 dec r6l 00236 bne sys_noswitch ; timeslice elapsed? 00237 00238 mov.w @_kernel_critsec_count,r6 ; check critical section 00239 beq sys_switch ; ok to switch 00240 mov.b #1,r6l ; wait another tick 00241 jmp sys_noswitch ; don't switch 00242 00243 sys_switch: 00244 mov.w @_tm_switcher_vector,r6 00245 jsr @r6 ; call task switcher 00246 00247 _systime_tm_return: 00248 mov.b @_tm_timeslice,r6l ; new timeslice 00249 00250 sys_noswitch: 00251 mov.b r6l,@_tm_current_slice 00252 " 00253 #endif 00254 " 00255 pop r0 00256 bclr #3,@0x91:8 ; reset compare A IRQ flag 00257 rts 00258 " 00259 ); 00260 #endif // DOXYGEN_SHOULD_SKIP_THIS 00261 00262 00264 00267 void systime_init(void) { 00268 systime_shutdown(); // shutdown hardware 00269 00270 sys_time=0l; // init timer 00271 00272 #ifdef CONF_TM 00273 tm_current_slice=tm_timeslice=TM_DEFAULT_SLICE; 00274 tm_switcher_vector=&rom_dummy_handler; // empty handler 00275 #endif 00276 00277 #ifdef CONF_DMOTOR 00278 dm_shutdown(); 00279 #endif 00280 00281 // configure 16-bit timer 00282 // compare B IRQ will fire after one msec 00283 // compare A IRQ will fire after another msec 00284 // counter is then reset 00285 // 00286 T_CSR = TCSR_RESET_ON_A; 00287 T_CR = TCR_CLOCK_32; 00288 T_OCR &= ~TOCR_OCRB; 00289 T_OCRA = 1000; 00290 T_OCR &= ~TOCR_OCRA; 00291 T_OCR |= TOCR_OCRB; 00292 T_OCRB = 500; 00293 00294 #if defined(CONF_TM) 00295 ocia_vector = &task_switch_handler; 00296 #else // CONF_TM 00297 ocia_vector = &subsystem_handler; 00298 #endif // CONF_TM 00299 ocib_vector = &subsystem_handler; 00300 T_IER |= (TIER_ENABLE_OCB | TIER_ENABLE_OCA); 00301 00302 nmi_vector = &clock_handler; 00303 WDT_CSR = WDT_CNT_PASSWORD | WDT_CNT_MSEC_64; // trigger every msec 00304 WDT_CSR = WDT_CSR_PASSWORD 00305 | WDT_CSR_CLOCK_64 00306 | WDT_CSR_WATCHDOG_NMI 00307 | WDT_CSR_ENABLE 00308 | WDT_CSR_MODE_WATCHDOG; 00309 } 00310 00312 00314 void systime_shutdown(void) { 00315 T_IER &= ~(TIER_ENABLE_OCA | TIER_ENABLE_OCB); // unhook compare A/B IRQs 00316 WDT_CSR &= ~WDT_CSR_ENABLE; // disable wd timer 00317 } 00318 00319 #ifdef CONF_TM 00320 00321 00323 void systime_set_switcher(void* switcher) { 00324 tm_switcher_vector=switcher; 00325 } 00326 00328 00330 void systime_set_timeslice(unsigned char slice) { 00331 if(slice>5) { // some minimum value 00332 tm_timeslice=slice; 00333 if(tm_current_slice>tm_timeslice) 00334 tm_current_slice=tm_timeslice; 00335 } 00336 } 00337 00338 #endif 00339 00340 #endif // CONF_TIME
brickOS is released under the
Mozilla Public License.
Original code copyright 1998-2002 by the authors. |