OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / timer.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/timer.c b/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/timer.c
new file mode 100644 (file)
index 0000000..c28c066
--- /dev/null
@@ -0,0 +1,184 @@
+\r
+#include "core.h"\r
+\r
+UI_TimerControl *timerctrl;\r
+\r
+UI_TimerControl *Initialize_ProgrammableIntervalTimer(void)\r
+{\r
+       timerctrl = (UI_TimerControl *)System_Memory_Allocate(sizeof(UI_TimerControl));\r
+\r
+       timerctrl->tick_10ms = 0;\r
+       timerctrl->TaskSwitch = &Timer_TaskSwitch_Invalid;\r
+\r
+//config watch\r
+       timerctrl->timer_root = Timer_Initialize();\r
+       Timer_Config(timerctrl->timer_root, 0xfffffff, Null, 0, True);\r
+       timerctrl->timer_root->timeout = 0xffffffff;\r
+       timerctrl->timer_root->flags.bit.running = True;\r
+\r
+//config PIT\r
+       IO_Out8(PIT_CTRL, 0x34);\r
+       IO_Out8(PIT_CNT0, 0x9c);\r
+       IO_Out8(PIT_CNT0, 0x2e);\r
+       System_GateDescriptor_Set(0x20, (uint)asm_InterruptHandler20, 0x02, AR_INTGATE32);\r
+       ProgrammableInterruptController_InterruptMask_Clear(0x00);\r
+\r
+       return timerctrl;\r
+}\r
+\r
+void InterruptHandler20(uint *esp)\r
+{\r
+       ProgrammableInterruptController_InterruptRequest_Complete(0x00);\r
+       timerctrl->tick_10ms++;\r
+\r
+       if(timerctrl->timer_root->timeout <= timerctrl->tick_10ms){\r
+               Timer_TimeOut();\r
+       }\r
+\r
+       if((timerctrl->tick_10ms & 0x00000003) == 0){\r
+               timerctrl->TaskSwitch();\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+void Timer_Set_TaskSwitch(void (*TaskSwitchFunction)(void))\r
+{\r
+       if(TaskSwitchFunction != Null){\r
+               timerctrl->TaskSwitch = TaskSwitchFunction;\r
+       } else{\r
+               timerctrl->TaskSwitch = Timer_TaskSwitch_Invalid;\r
+       }\r
+       return;\r
+}\r
+\r
+void Timer_TaskSwitch_Invalid(void)\r
+{\r
+       return;\r
+}\r
+\r
+UI_Timer *Timer_Initialize(void)\r
+{\r
+       UI_Timer *timer;\r
+\r
+       timer = System_Memory_Allocate(sizeof(UI_Timer));\r
+\r
+       timer->flags.bit.initialized = True;\r
+\r
+       #ifdef CHNOSPROJECT_DEBUG_TIMER\r
+               debug("Timer_Initialize:[0x%08X]\n", timer);\r
+       #endif\r
+\r
+       return timer;\r
+}\r
+\r
+uint Timer_Config(UI_Timer *timer, uint tick_ms, DATA_FIFO32 *fifo, uint fifo_putdata, bool interval)\r
+{\r
+       if(timer == Null){\r
+               return 1;\r
+       }\r
+\r
+       if(!timer->flags.bit.initialized){\r
+               return 2;\r
+       }\r
+\r
+       timer->tick = tick_ms / 10;\r
+       timer->fifo = fifo;\r
+       timer->fifo_putdata = fifo_putdata;\r
+       timer->flags.bit.interval = interval;\r
+\r
+       timer->flags.bit.configured = True;\r
+\r
+       return 0;\r
+}\r
+\r
+uint Timer_Run(UI_Timer *timer)\r
+{\r
+       uint eflags;\r
+       UI_Timer **search;\r
+\r
+       if(timer == Null){\r
+               return 1;\r
+       }\r
+\r
+       if(!timer->flags.bit.configured){\r
+               return 2;\r
+       }\r
+\r
+       if(timer->flags.bit.running){\r
+               return 3;\r
+       }\r
+\r
+       timer->timeout = timer->tick + timerctrl->tick_10ms;\r
+       search = &timerctrl->timer_root;\r
+\r
+       eflags = IO_Load_EFlags();\r
+\r
+       for(;;){\r
+               if((*search) == Null){\r
+                       #ifdef CHNOSPROJECT_DEBUG_TIMER\r
+                               debug("Timer_Run:Invalid link. Abort.\n");\r
+                       #endif\r
+                       INT_3();\r
+               }\r
+               if((*search)->timeout > timer->timeout){\r
+                       IO_CLI();\r
+                       timer->root_next = *search;\r
+                       *search = timer;\r
+                       timer->tree_next = Null;\r
+                       timer->flags.bit.running = True;\r
+                       break;\r
+               }\r
+               if((*search)->timeout == timer->timeout){\r
+                       IO_CLI();\r
+                       search = &(*search)->tree_next;\r
+                       for(;;){\r
+                               if(*search == Null){\r
+                                       break;\r
+                               }\r
+                               search = &(*search)->tree_next;\r
+                       }\r
+                       timer->root_next = Null;\r
+                       *search = timer;\r
+                       timer->tree_next = Null;\r
+                       timer->flags.bit.running = True;\r
+                       break;\r
+               }\r
+               search = &(*search)->root_next;\r
+       }\r
+\r
+       IO_Store_EFlags(eflags);\r
+\r
+       return 0;\r
+}\r
+\r
+uint Timer_TimeOut(void)\r
+{\r
+       UI_Timer *search, *old;\r
+\r
+       search = timerctrl->timer_root;\r
+       timerctrl->timer_root = timerctrl->timer_root->root_next;\r
+\r
+       for(;;){\r
+               if(search->fifo != Null){\r
+                       FIFO32_Put(search->fifo, search->fifo_putdata);\r
+               }\r
+               old = search;\r
+               search = old->tree_next;\r
+               old->tree_next = 0;\r
+               old->flags.bit.running = False;\r
+               if(old->flags.bit.interval){\r
+                       Timer_Run(old);\r
+               }\r
+               if(search == Null){\r
+                       break;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+uint Timer_GetTick(void)\r
+{\r
+       return timerctrl->tick_10ms;\r
+}\r
+\r