brickOS Kernel Developer v0.9.0
systime.c
Go to the documentation of this file.
1
6/*
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.0 (the "License"); you may not use this file except in
9 * compliance with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
14 * License for the specific language governing rights and limitations
15 * under the License.
16 *
17 * The Original Code is legOS code, released October 17, 1999.
18 *
19 * The Initial Developer of the Original Code is Markus L. Noga.
20 * Portions created by Markus L. Noga are Copyright (C) 1999
21 * Markus L. Noga. All Rights Reserved.
22 *
23 * Contributor(s): Markus L. Noga <markus@noga.de>
24 * David Van Wagner <davevw@alumni.cse.ucsc.edu>
25 */
26
27/*
28 * 2000.05.01 - Paolo Masetti <paolo.masetti@itlug.org>
29 *
30 * - Added battery indicator handler
31 *
32 * 2000.08.12 - Rossz Vámos-Wentworth <rossw@jps.net>
33 *
34 * - Added idle shutdown handler
35 *
36 */
37
38#include <config.h>
39
40#ifdef CONF_TIME
41
42#include <sys/time.h>
43#include <sys/h8.h>
44#include <sys/irq.h>
45#include <sys/dmotor.h>
46#include <sys/dsound.h>
47#include <sys/battery.h>
48#include <sys/critsec.h>
49#ifdef CONF_AUTOSHUTOFF
50#include <sys/timeout.h>
51#endif
52
54//
55// Global Variables
56//
58
60
64
66//
67// Internal Variables
68//
70
71#ifdef CONF_TM
72volatile unsigned char tm_timeslice;
73volatile unsigned char tm_current_slice;
74
76#endif
77
78
80//
81// Functions
82//
84
86
88extern void clock_handler(void);
89#ifndef DOXYGEN_SHOULD_SKIP_THIS
90__asm__("\n\
91.text\n\
92.align 1\n\
93.global _clock_handler\n\
94 _clock_handler:\n\
95 mov.w #0x5a07,r6 ; reset wd timer to 6\n\
96 mov.w r6,@0xffa8\n\
97\n\
98 mov.w @_sys_time+2,r6 ; lower 8 bits\n\
99 add.b #0x1,r6l ; inc lower 4 bits\n\
100 addx #0x0,r6h ; add carry to top 4 bits\n\
101 mov.w r6,@_sys_time+2\n\
102 bcc sys_nohigh ; if carry, inc upper 8 bits\n\
103 mov.w @_sys_time,r6 ; \n\
104 add.b #0x1,r6l ; inc lower 4 bits\n\
105 addx #0x0,r6h ; add carry to top 4 bits\n\
106 mov.w r6,@_sys_time\n\
107 sys_nohigh: \n\
108 rts\n\
109 ");
110#endif // DOXYGEN_SHOULD_SKIP_THIS
111
113
117extern void subsystem_handler(void);
118
120
122extern void task_switch_handler(void);
123#ifndef DOXYGEN_SHOULD_SKIP_THIS
124__asm__("\n\
125.text\n\
126.align 1\n\
127.global _subsystem_handler\n\
128.global _task_switch_handler\n\
129.global _systime_tm_return\n\
130_subsystem_handler:\n\
131 ; r6 saved by ROM\n\
132\n\
133 push r0 ; both motors & task\n\
134 ; switcher need this reg.\n\
135 "
136
137#ifdef CONF_DSOUND
138 "\n\
139 jsr _dsound_handler ; call sound handler\n\
140 "
141#endif // CONF_DSOUND
142
143#ifdef CONF_LNP
144 "\n\
145 mov.w @_lnp_timeout_counter,r6 ; check LNP timeout counter\n\
146 subs #0x1,r6\n\
147 mov.w r6,r6 ; subs doesn't change flags!\n\
148 bne sys_noreset\n\
149 \n\
150 jsr _lnp_integrity_reset\n\
151 mov.w @_lnp_timeout,r6 ; reset timeout\n\
152\n\
153 sys_noreset:\n\
154 mov.w r6,@_lnp_timeout_counter\n\
155 "
156#endif // CONF_LNP
157
158#ifdef CONF_DKEY
159 "\n\
160 jsr _dkey_handler\n\
161 "
162#endif // CONF_DKEY
163
164#ifndef CONF_TM
166 "\n\
167 mov.w @_battery_refresh_counter,r6\n\
168 subs #0x1,r6\n\
169 bne batt_norefresh\n\
170\n\
171 jsr _battery_refresh\n\
172 mov.w @_battery_refresh_period,r6\n\
173\n\
174 batt_norefresh:\n\
175 mov.w r6,@_battery_refresh_counter\n\
176 "
177#endif // CONF_BATTERY_INDICATOR
178#endif // CONF_TM
179
180#ifdef CONF_AUTOSHUTOFF
181 "\n\
182 mov.w @_auto_shutoff_counter,r6\n\
183 subs #0x1,r6\n\
184 bne auto_notshutoff\n\
185\n\
186 jsr _autoshutoff_check\n\
187 mov.w @_auto_shutoff_period,r6\n\
188 \n\
189 auto_notshutoff:\n\
190 mov.w r6,@_auto_shutoff_counter\n\
191 "
192#endif // CONF_AUTOSHUTOFF
193
194#ifdef CONF_VIS
195 "\n\
196 mov.b @_vis_refresh_counter,r6l\n\
197 dec r6l\n\
198 bne vis_norefresh\n\
199 \n\
200 jsr _vis_handler\n\
201 mov.b @_vis_refresh_period,r6l\n\
202 \n\
203 vis_norefresh:\n\
204 mov.b r6l,@_vis_refresh_counter\n\
205 "
206#endif // CONF_VIS
207
208#ifdef CONF_LCD_REFRESH
209 "\n\
210 mov.b @_lcd_refresh_counter,r6l\n\
211 dec r6l\n\
212 bne lcd_norefresh\n\
213 \n\
214 jsr _lcd_refresh_next_byte\n\
215 mov.b @_lcd_refresh_period,r6l\n\
216 \n\
217 lcd_norefresh:\n\
218 mov.b r6l,@_lcd_refresh_counter\n\
219 "
220#endif // CONF_LCD_REFRESH
221 "\n\
222 bclr #2,@0x91:8 ; reset compare B IRQ flag\n\
223 "
224#ifdef CONF_TM
225 "\n\
226 pop r0 ; if fallthrough, pop r0\n\
227 _task_switch_handler:\n\
228 push r0 ; save r0\n\
229\n\
230 mov.b @_tm_current_slice,r6l\n\
231 dec r6l\n\
232 bne sys_noswitch ; timeslice elapsed?\n\
233\n\
234 mov.w @_kernel_critsec_count,r6 ; check critical section\n\
235 beq sys_switch ; ok to switch\n\
236 mov.b #1,r6l ; wait another tick\n\
237 jmp sys_noswitch ; don't switch\n\
238\n\
239 sys_switch:\n\
240 mov.w @_tm_switcher_vector,r6\n\
241 jsr @r6 ; call task switcher\n\
242 \n\
243 _systime_tm_return:\n\
244 mov.b @_tm_timeslice,r6l ; new timeslice\n\
245\n\
246 sys_noswitch:\n\
247 mov.b r6l,@_tm_current_slice\n\
248 "
249#endif // CONF_TM
250
251#ifdef CONF_DMOTOR
252 "\n\
253 jsr _dm_handler ; call motor driver\n\
254 "
255#endif // CONF_DMOTOR
256
257 "\n\
258 pop r0\n\
259 bclr #3,@0x91:8 ; reset compare A IRQ flag\n\
260 rts\n\
261 "
262);
263#endif // DOXYGEN_SHOULD_SKIP_THIS
264
265
267
270void systime_init(void) {
271 systime_shutdown(); // shutdown hardware
272
273 sys_time=0l; // init timer
274
275#ifdef CONF_TM
277 tm_switcher_vector=&rom_dummy_handler; // empty handler
278#endif
279
280#ifdef CONF_DMOTOR
281 dm_shutdown();
282#endif
283
284 // configure 16-bit timer
285 // compare B IRQ will fire after one msec
286 // compare A IRQ will fire after another msec
287 // counter is then reset
288 //
291 T_OCR &= ~TOCR_OCRB;
292 T_OCRA = 1000;
293 T_OCR &= ~TOCR_OCRA;
294 T_OCR |= TOCR_OCRB;
295 T_OCRB = 500;
296
297#if defined(CONF_TM)
299#else // CONF_TM
301#endif // CONF_TM
304
306 WDT_CSR = WDT_CNT_PASSWORD | WDT_CNT_MSEC_64; // trigger every msec
312}
313
315
318 T_IER &= ~(TIER_ENABLE_OCA | TIER_ENABLE_OCB); // unhook compare A/B IRQs
319 WDT_CSR &= ~WDT_CSR_ENABLE; // disable wd timer
320}
321
322#ifdef CONF_TM
324
326void systime_set_switcher(void* switcher) {
327 tm_switcher_vector=switcher;
328}
329
331
333void systime_set_timeslice(unsigned char slice) {
334 if(slice>5) { // some minimum value
335 tm_timeslice=slice;
338 }
339}
340
341#endif
342
344
353.text\n\
354.align 1\n\
355.global _get_system_up_time\n\
356_get_system_up_time:\n\
357 push r2\n\
358 try_again:\n\
359 mov.w @_sys_time+2, r1\n\
360 mov.w @_sys_time, r0\n\
361 mov.w @_sys_time+2, r2\n\
362 cmp r2, r1\n\
363 bne try_again\n\
364 pop r2\n\
365 rts\n\
366");
367
368#endif // CONF_TIME
Internal Interface: battery handling.
kernel configuration file
#define CONF_VIS
generic visualization.
Definition config.h:45
#define CONF_AUTOSHUTOFF
power down after x min of inactivity
Definition config.h:38
#define CONF_TM
task management
Definition config.h:37
#define CONF_LCD_REFRESH
automatic display updates
Definition config.h:70
#define CONF_BATTERY_INDICATOR
automatic update of lcd battery indicator
Definition config.h:69
#define CONF_LNP
link networking protocol
Definition config.h:50
#define CONF_DMOTOR
direct motor
Definition config.h:75
#define CONF_DKEY
debounced key driver
Definition config.h:68
#define CONF_DSOUND
direct sound
Definition config.h:73
Internal Interface: H8/3297 processor registers.
#define WDT_CNT_MSEC_64
Definition h8.h:448
volatile unsigned char T_CSR
16-bit timer control / status register
#define WDT_CSR_ENABLE
Definition h8.h:429
unsigned T_OCRB
16-bit timer output compare register B
#define WDT_CNT_PASSWORD
Definition h8.h:446
#define TCR_CLOCK_32
Definition h8.h:106
#define WDT_CSR_PASSWORD
Definition h8.h:428
unsigned char T_CR
16-bit timer control register
unsigned char T_IER
16-bit timer interrupt enable register
volatile unsigned int WDT_CSR
watch dog timer control register
#define WDT_CSR_CLOCK_64
Definition h8.h:436
#define TCSR_RESET_ON_A
Definition h8.h:93
#define WDT_CSR_MODE_WATCHDOG
Definition h8.h:430
#define TIER_ENABLE_OCB
Definition h8.h:79
unsigned T_OCRA
16-bit timer output compare register A
#define WDT_CSR_WATCHDOG_NMI
Definition h8.h:432
#define TOCR_OCRB
Definition h8.h:113
#define TIER_ENABLE_OCA
Definition h8.h:78
unsigned char T_OCR
16-bit timer output control register
Internal LNP Interface: RCX redirected IRQ vectors.
void * ocia_vector
OCIA interrupt vector.
void rom_dummy_handler()
address of an RTS instruction
void * nmi_vector
NMI interrupt vector.
void * ocib_vector
OCIB interrupt vector.
Interface: kernel level critical sections.
Internal Interface: direct motor control.
void dm_shutdown(void)
shutdown motors
Internal Interface: direct sound control.
Internal Interface: system time functions.
#define TM_DEFAULT_SLICE
default multitasking timeslice
Definition time.h:44
void * tm_switcher_vector
pointer to task switcher
Definition systime.c:75
void task_switch_handler(void)
task switch handler called every msec
time_t get_system_up_time(void)
retrieve the current system time
void systime_init(void)
initialize system timer
Definition systime.c:270
void systime_set_switcher(void *switcher)
set task switcher vector
Definition systime.c:326
volatile unsigned char tm_timeslice
task time slice
Definition systime.c:72
void systime_set_timeslice(unsigned char slice)
set multitasking timeslice in ms
Definition systime.c:333
volatile unsigned char tm_current_slice
current time remaining
Definition systime.c:73
volatile time_t sys_time
current system time in ms
Definition systime.c:63
void subsystem_handler(void)
subsystem handler for every 2nd msec
void systime_shutdown(void)
shutdown system timer
Definition systime.c:317
void clock_handler(void)
clock handler triggered on the WDT overflow (every msec) on the NMI
__asm__("\n\ .text\n\ .align 1\n\ .global _get_system_up_time\n\ _get_system_up_time:\n\ push r2\n\ try_again:\n\ mov.w @_sys_time+2, r1\n\ mov.w @_sys_time, r0\n\ mov.w @_sys_time+2, r2\n\ cmp r2, r1\n\ bne try_again\n\ pop r2\n\ rts\n\ ")
unsigned long time_t
time type
Definition time.h:50
Internal Interface: Powerdown Timer Routines.