Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

kernel/systime.c

Go to the documentation of this file.
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__("
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.

Generated on Sat Jul 26 23:55:00 2003 for brickOS Kernel Developer by doxygen 1.3.2