Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

IdeTimer.c

Go to the documentation of this file.
00001 /*!     \file drivers/ata/IdeTimer.c
00002  *      \brief IDE driver::Timing.
00003  *      \author Luca Giovacchini
00004  *      \date Last update: 2003-11-07
00005  *      \note Copyright (©) 2003 Luca Giovacchini
00006  *
00007  *      This driver is based on Atadrv by Hale Landis
00008  *      but it is completely rearranged for the minirighi32.
00009  *      \n
00010  *      <b>IMPORTANT!!!</b>\n
00011  *      Here you can find all subs regarding waiting and timing.
00012  *      Look at the specific sub comment.
00013  */
00014 
00015 #include <arch/i386.h>  // for Enable() Disable()
00016 
00017 #include <kernel/clock.h>   // for Ticks
00018 #include <kernel/console.h>   // for kprintf
00019 #include <kernel/IdeTimer.h>
00020 #include <kernel/IdeLow.h>
00021 #include <kernel/Ide.h>
00022 #include <kernel/keyboard.h>
00023 #include <kernel/task.h>    // for Idle()
00024 
00025 extern dword ticks;
00026 extern IdeChannel_Struct * CurrentChannel;
00027 
00028 // ************************* Idle ***************************
00029 // TODO: we can move the Get_If Set_If in the caller sub
00030 //               it will be more efficient
00031 // **********************************************************
00032 void GoIdle()
00033 {
00034         dword IF = GET_IF();
00035         // Auto-sleep //
00036         enable();
00037         idle(); 
00038         SET_IF(IF);
00039 }
00040 
00041 // ************************ Delay ***************************
00042 // Start a timer
00043 // **********************************************************
00044 void Delay(dword ms)
00045 {
00046         
00047         dword Start=ticks;
00048         // we work with integer and not float, we have resolution greater than 1 ms
00049         // so we must trunc at the tick higher expected
00050         dword Stop;
00051         byte Cross;
00052         if ( (ms*HZ)%1000 == 0 )
00053                 // We can wait exactely ms 
00054                 Stop=Start+ms*HZ/1000;
00055         else
00056                 // We must wait little more than ms because our 
00057                 // timer resolution can't permit to wait exactely ms
00058                 Stop=(Start+ms*HZ/1000)+1;
00059 
00060         Cross=(Stop<Start);
00061         // need to pay attention while waiting 
00062         // for overflow of ticks and overflow of Stop
00063         while ( Cross ? (ticks >= Start) || (ticks < Stop) : (ticks>=Start) && (ticks<Stop) )
00064                 GoIdle();
00065 
00066 }
00067 
00068 // ********************** TimerStart ************************
00069 // Start a timer (filling a timer struct)
00070 // **********************************************************
00071 Timer_Struct TimerStart(dword ms) 
00072 {       
00073         Timer_Struct Timer;
00074         Timer.Start=ticks;
00075 
00076         if ( ms*HZ % 1000 == 0 )
00077                 // We can wait exactely ms
00078                 Timer.Stop=Timer.Start+ms*HZ/1000;
00079         else
00080                 // We must wait little more than ms because our
00081                 // timer resolution can't permit to wait exactely ms
00082                 Timer.Stop=(Timer.Start+ms*HZ/1000)+1;
00083         Timer.Cross=(Timer.Stop<Timer.Start);
00084         return Timer;
00085 }
00086 
00087 // ********************* TimerElapsed ***********************
00088 // Check if timer is elapsed
00089 // **********************************************************
00090 int TimerElapsed(Timer_Struct Timer)
00091 {
00092         // need to pay attention for overflow of ticks while waiting
00093         // and overflow of Stop
00094         return ( Timer.Cross ? (ticks < Timer.Start) && (ticks >= Timer.Stop) : (ticks<Timer.Start) || (ticks>=Timer.Stop) );
00095 }
00096 
00097 
00098 // ********************** WaitForInt ************************
00099 // Wait for interrupt
00100 // The Timer MUST be started previously or this code will
00101 // wait an undefined period of time
00102 // **********************************************************
00103 int WaitForInt(Timer_Struct Timer)
00104 {
00105         while (TRUE)
00106         {
00107                 if (CurrentChannel->IntDone == TRUE)
00108                 {
00109                         // reset interrupt flag;
00110                         CurrentChannel->IntDone=FALSE;
00111                         return FALSE;
00112                 }
00113 
00114                 if ( TimerElapsed(Timer) )
00115                         return TRUE;
00116 
00117                 GoIdle();
00118         }
00119 }
00120 
00121 // ********************** WaitForBsy ************************
00122 // Wait for BSY = 0
00123 // The Timer MUST be started previously or this code will
00124 // wait an undefined period of time
00125 // **********************************************************
00126 int WaitForBsy(Timer_Struct Timer,word Port)
00127 {
00128         byte Status=0;
00129         
00130         while (TRUE)
00131         {
00132                 Status = InPortAta( Port );       // poll for not busy
00133                 if ( ( Status & HDC_STAT_BSY ) == 0 )
00134                         return FALSE;
00135                 
00136                 if ( TimerElapsed(Timer) )               // time out yet ?
00137                         return TRUE;
00138                 
00139                 GoIdle();
00140         }
00141 }
00142 
00143 // ********************** AtapiDelay ************************
00144 // Execute a delay only for atapi device
00145 // **********************************************************
00146 void AtapiDelay(int Dev)
00147 {
00148         if ( CurrentChannel->Device[Dev].Type == CC_DEVTYPE_ATAPI )
00149                 delay(HDC_ATAPIDELAY);
00150 }
00151 
00152 // ********************** WaitKeyPress **********************
00153 // Wait user press a key
00154 // is for shell ide command and visualization
00155 // **********************************************************
00156 void WaitKeyPress(char * Message)
00157 {
00158         int Tmp;
00159         if (Message)
00160                 kprintf("\n\r%s\n\r",Message);
00161         Tmp=kgetchar();
00162 }
00163 
00164 
00165 

Generated on Fri Feb 20 15:32:15 2004 for Minirighi by doxygen1.2.18