OSDN Git Service

AI003:config.txt, words.txtを追加。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / timer.c
1 \r
2 #include "core.h"\r
3 \r
4 UI_TimerControl *timerctrl;\r
5 \r
6 UI_TimerControl *Initialize_ProgrammableIntervalTimer(void)\r
7 {\r
8         timerctrl = (UI_TimerControl *)System_Memory_Allocate(sizeof(UI_TimerControl));\r
9 \r
10         timerctrl->tick_10ms = 0;\r
11         timerctrl->TaskSwitch = &Timer_TaskSwitch_Invalid;\r
12 \r
13 //config watch\r
14         timerctrl->timer_root = Timer_Initialize();\r
15         Timer_Config(timerctrl->timer_root, 0xfffffff, Null, 0, True);\r
16         timerctrl->timer_root->timeout = 0xffffffff;\r
17         timerctrl->timer_root->flags.bit.running = True;\r
18 \r
19 //config PIT\r
20         IO_Out8(PIT_CTRL, 0x34);\r
21         IO_Out8(PIT_CNT0, 0x9c);\r
22         IO_Out8(PIT_CNT0, 0x2e);\r
23         System_GateDescriptor_Set(0x20, (uint)asm_InterruptHandler20, 0x02, AR_INTGATE32);\r
24         ProgrammableInterruptController_InterruptMask_Clear(0x00);\r
25 \r
26         return timerctrl;\r
27 }\r
28 \r
29 void InterruptHandler20(uint *esp)\r
30 {\r
31         ProgrammableInterruptController_InterruptRequest_Complete(0x00);\r
32         timerctrl->tick_10ms++;\r
33 \r
34         if(timerctrl->timer_root->timeout <= timerctrl->tick_10ms){\r
35                 Timer_TimeOut();\r
36         }\r
37 \r
38         if((timerctrl->tick_10ms & 0x00000003) == 0){\r
39                 timerctrl->TaskSwitch();\r
40         }\r
41 \r
42         return;\r
43 }\r
44 \r
45 void Timer_Set_TaskSwitch(void (*TaskSwitchFunction)(void))\r
46 {\r
47         if(TaskSwitchFunction != Null){\r
48                 timerctrl->TaskSwitch = TaskSwitchFunction;\r
49         } else{\r
50                 timerctrl->TaskSwitch = Timer_TaskSwitch_Invalid;\r
51         }\r
52         return;\r
53 }\r
54 \r
55 void Timer_TaskSwitch_Invalid(void)\r
56 {\r
57         return;\r
58 }\r
59 \r
60 UI_Timer *Timer_Initialize(void)\r
61 {\r
62         UI_Timer *timer;\r
63 \r
64         timer = System_Memory_Allocate(sizeof(UI_Timer));\r
65 \r
66         timer->flags.bit.initialized = True;\r
67 \r
68         #ifdef CHNOSPROJECT_DEBUG_TIMER\r
69                 debug("Timer_Initialize:[0x%08X]\n", timer);\r
70         #endif\r
71 \r
72         return timer;\r
73 }\r
74 \r
75 uint Timer_Config(UI_Timer *timer, uint tick_ms, DATA_FIFO32 *fifo, uint fifo_putdata, bool interval)\r
76 {\r
77         if(timer == Null){\r
78                 return 1;\r
79         }\r
80 \r
81         if(!timer->flags.bit.initialized){\r
82                 return 2;\r
83         }\r
84 \r
85         timer->tick = tick_ms / 10;\r
86         timer->fifo = fifo;\r
87         timer->fifo_putdata = fifo_putdata;\r
88         timer->flags.bit.interval = interval;\r
89 \r
90         timer->flags.bit.configured = True;\r
91 \r
92         return 0;\r
93 }\r
94 \r
95 uint Timer_Run(UI_Timer *timer)\r
96 {\r
97         uint eflags;\r
98         UI_Timer **search;\r
99 \r
100         if(timer == Null){\r
101                 return 1;\r
102         }\r
103 \r
104         if(!timer->flags.bit.configured){\r
105                 return 2;\r
106         }\r
107 \r
108         if(timer->flags.bit.running){\r
109                 return 3;\r
110         }\r
111 \r
112         timer->timeout = timer->tick + timerctrl->tick_10ms;\r
113         search = &timerctrl->timer_root;\r
114 \r
115         eflags = IO_Load_EFlags();\r
116 \r
117         for(;;){\r
118                 if((*search) == Null){\r
119                         #ifdef CHNOSPROJECT_DEBUG_TIMER\r
120                                 debug("Timer_Run:Invalid link. Abort.\n");\r
121                         #endif\r
122                         INT_3();\r
123                 }\r
124                 if((*search)->timeout > timer->timeout){\r
125                         IO_CLI();\r
126                         timer->root_next = *search;\r
127                         *search = timer;\r
128                         timer->tree_next = Null;\r
129                         timer->flags.bit.running = True;\r
130                         break;\r
131                 }\r
132                 if((*search)->timeout == timer->timeout){\r
133                         IO_CLI();\r
134                         search = &(*search)->tree_next;\r
135                         for(;;){\r
136                                 if(*search == Null){\r
137                                         break;\r
138                                 }\r
139                                 search = &(*search)->tree_next;\r
140                         }\r
141                         timer->root_next = Null;\r
142                         *search = timer;\r
143                         timer->tree_next = Null;\r
144                         timer->flags.bit.running = True;\r
145                         break;\r
146                 }\r
147                 search = &(*search)->root_next;\r
148         }\r
149 \r
150         IO_Store_EFlags(eflags);\r
151 \r
152         return 0;\r
153 }\r
154 \r
155 uint Timer_TimeOut(void)\r
156 {\r
157         UI_Timer *search, *old;\r
158 \r
159         search = timerctrl->timer_root;\r
160         timerctrl->timer_root = timerctrl->timer_root->root_next;\r
161 \r
162         for(;;){\r
163                 if(search->fifo != Null){\r
164                         FIFO32_Put(search->fifo, search->fifo_putdata);\r
165                 }\r
166                 old = search;\r
167                 search = old->tree_next;\r
168                 old->tree_next = 0;\r
169                 old->flags.bit.running = False;\r
170                 if(old->flags.bit.interval){\r
171                         Timer_Run(old);\r
172                 }\r
173                 if(search == Null){\r
174                         break;\r
175                 }\r
176         }\r
177         return 0;\r
178 }\r
179 \r
180 uint Timer_GetTick(void)\r
181 {\r
182         return timerctrl->tick_10ms;\r
183 }\r
184 \r