Changeset d57c04e in rtems


Ignore:
Timestamp:
Dec 5, 2000, 4:49:23 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
57fe91f
Parents:
327a93a4
Message:

2000-12-05 Eric Valette <valette@…>

  • console/inch.c, console/keyboard.c, console/pc_keyb.c, console/vt.c, include/bsp.h: Correct incorrect interrupt level handling in new keyboard management code. Correct BSP_poll_char initialization routine.
  • start/start.S, startup/bspstart.c: Correct when the video is initialized.
  • timer/timer.c (Calibrate_1ms_loop): Address problem where this did not work correctly on all PC speeds. The new calibrate routine has been tested on Pentium 166, pentium II 200, pentium III 300 Mhz and does work as expected.
Location:
c/src/lib/libbsp/i386/pc386
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/ChangeLog

    r327a93a4 rd57c04e  
     12000-12-05       Eric Valette <valette@crf.canon.fr>
     2
     3        * console/inch.c, console/keyboard.c, console/pc_keyb.c,
     4        console/vt.c, include/bsp.h: Correct incorrect interrupt level
     5        handling in new keyboard management code.  Correct
     6        BSP_poll_char initialization routine.
     7        * start/start.S, startup/bspstart.c: Correct when the video is
     8        initialized.
     9        * timer/timer.c (Calibrate_1ms_loop): Address problem where this
     10        did not work correctly on all PC speeds. The new calibrate routine
     11        has been tested on Pentium 166, pentium II 200, pentium III
     12        300 Mhz and does work as expected.
     13
    1142000-12-05      Joel Sherrill <joel@OARcorp.com>
    215
  • c/src/lib/libbsp/i386/pc386/console/inch.c

    r327a93a4 rd57c04e  
    3737| Constants
    3838+--------------------------------------------------------------------------*/
    39 #define KBD_BUF_SIZE    256
     39#define KBD_CTL      0x61  /* -------------------------------- */
     40#define KBD_DATA     0x60  /* Ports for PC keyboard controller */
     41#define KBD_STATUS   0x64  /* -------------------------------- */
     42
     43#define KBD_BUF_SIZE 256
     44
     45/*-------------------------------------------------------------------------+
     46| Global Variables
     47+--------------------------------------------------------------------------*/
     48static char key_map[] =
     49{
     50  0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
     51  'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
     52  'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
     53  0134,'z','x','c','v','b','n','m',',','.','/',0x80,
     54  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
     55  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
     56  0x80,0x80,0x80,'0',0177
     57}; /* Keyboard scancode -> character map with no modifiers.       */
     58
     59static char shift_map[] =
     60{
     61  0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
     62  'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
     63  'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
     64  '|','Z','X','C','V','B','N','M','<','>','?',0x80,
     65  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
     66  0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
     67  '1','2','3','0',177
     68}; /* Keyboard scancode -> character map with SHIFT key modifier. */
     69
    4070
    4171static unsigned short   kbd_buffer[KBD_BUF_SIZE];
     
    5888
    5989
    60 
    61 #define disable __asm__ __volatile__("cli")
    62 #define enable  __asm__ __volatile__("sti");
     90/*-------------------------------------------------------------------------+
     91|         Function: _IBMPC_scankey
     92|      Description: This function can be called during a poll for input, or by
     93|                   an ISR. Basically any time you want to process a keypress.
     94| Global Variables: key_map, shift_map.
     95|        Arguments: outChar - character read in case of a valid reading,
     96|                   otherwise unchanged.
     97|          Returns: TRUE in case a valid character has been read,
     98|                   FALSE otherwise.
     99+--------------------------------------------------------------------------*/
     100static rtems_boolean
     101_IBMPC_scankey(char *outChar)
     102{
     103  unsigned char inChar;
     104  static int alt_pressed   = 0;
     105  static int ctrl_pressed  = 0;
     106  static int shift_pressed = 0;
     107  static int caps_pressed  = 0;
     108  static int extended      = 0;
     109
     110  *outChar = '\0'; /* default value if we return FALSE */
     111
     112  /* Read keyboard controller, toggle enable */
     113  inport_byte(KBD_CTL, inChar);
     114  outport_byte(KBD_CTL, inChar & ~0x80);
     115  outport_byte(KBD_CTL, inChar | 0x80);
     116  outport_byte(KBD_CTL, inChar & ~0x80);
     117
     118  /* See if it has data */
     119  inport_byte(KBD_STATUS, inChar);
     120  if ((inChar & 0x01) == 0)
     121    return FALSE;
     122
     123  /* Read the data.  Handle nonsense with shift, control, etc. */
     124  inport_byte(KBD_DATA, inChar);
     125
     126  if (extended)
     127    extended--;
     128
     129  switch (inChar)
     130  {
     131    case 0xe0:
     132      extended = 2;
     133      return FALSE;
     134      break;
     135
     136    case 0x38:
     137      alt_pressed = 1;
     138      return FALSE;
     139      break;
     140    case 0xb8:
     141      alt_pressed = 0;
     142      return FALSE;
     143      break;
     144
     145    case 0x1d:
     146      ctrl_pressed = 1;
     147      return FALSE;
     148      break;
     149    case 0x9d:
     150      ctrl_pressed = 0;
     151      return FALSE;
     152      break;
     153
     154    case 0x2a:
     155      if (extended)
     156        return FALSE;
     157    case 0x36:
     158      shift_pressed = 1;
     159      return FALSE;
     160      break;
     161    case 0xaa:
     162      if (extended)
     163        return FALSE;
     164    case 0xb6:
     165      shift_pressed = 0;
     166      return FALSE;
     167      break;
     168
     169    case 0x3a:
     170      caps_pressed = 1;
     171      return FALSE;
     172      break;
     173    case 0xba:
     174      caps_pressed = 0;
     175      return FALSE;
     176      break;
     177
     178    case 0x53:
     179      if (ctrl_pressed && alt_pressed)
     180        rtemsReboot(); /* ctrl+alt+del -> reboot */
     181      break;
     182
     183    /*
     184     * Ignore unrecognized keys--usually arrow and such
     185     */
     186    default:
     187      if ((inChar & 0x80) || (inChar > 0x39))
     188      /* High-bit on means key is being released, not pressed */
     189        return FALSE;
     190      break;
     191  } /* switch */
     192
     193  /* Strip high bit, look up in our map */
     194  inChar &= 0x7f;
     195  if (ctrl_pressed)
     196  {
     197    *outChar = key_map[inChar];
     198    *outChar &= 037;
     199  }
     200  else
     201  {
     202    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
     203    if (caps_pressed)
     204    {
     205      if (*outChar >= 'A' && *outChar <= 'Z')
     206        *outChar += 'a' - 'A';
     207      else if (*outChar >= 'a' && *outChar <= 'z')
     208        *outChar -= 'a' - 'A';
     209    }
     210  }
     211
     212  return TRUE;
     213} /* _IBMPC_scankey */
     214
     215/*-------------------------------------------------------------------------+
     216|         Function: _IBMPC_chrdy
     217|      Description: Check keyboard ISR buffer and return character if not empty.
     218| Global Variables: kbd_buffer, kbd_first, kbd_last.
     219|        Arguments: c - character read if keyboard buffer not empty, otherwise
     220|                   unchanged.
     221|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
     222+--------------------------------------------------------------------------*/
     223static rtems_boolean
     224_IBMPC_chrdy(char *c)
     225{
     226  /* FIX ME!!! It doesn't work without something like the following line.
     227     Find out why! */
     228  printk("");
     229
     230  /* Check buffer our ISR builds */
     231  if (kbd_first != kbd_last)
     232  {
     233    *c = kbd_buffer[kbd_first];
     234
     235    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
     236    return TRUE;
     237  }
     238  else
     239    return FALSE;
     240} /* _IBMPC_chrdy */
     241
     242
     243/*-------------------------------------------------------------------------+
     244|         Function: _IBMPC_inch
     245|      Description: Poll keyboard until a character is ready and return it.
     246| Global Variables: None.
     247|        Arguments: None.
     248|          Returns: character read from keyboard.
     249+--------------------------------------------------------------------------*/
     250char
     251_IBMPC_inch(void)
     252{
     253    char c;
     254    while (!_IBMPC_chrdy(&c))
     255      continue;
     256
     257    return c;
     258} /* _IBMPC_inch */
     259
     260 
     261 /*
     262  * Routine that can be used before interrupt management is initialized.
     263  */
     264 
     265char
     266BSP_wait_polled_input(void)
     267{
     268  char c;
     269  while (!_IBMPC_scankey(&c))
     270    continue;
     271
     272  return c;
     273}
     274
    63275/*
    64276 * Check if a key has been pressed. This is a non-destructive
     
    67279int rtems_kbpoll( void )
    68280{
    69   int rc;
    70   disable;
     281  int rc,level;
     282
     283  _CPU_ISR_Disable(level);
     284
    71285  rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
    72   enable;
     286
     287  _CPU_ISR_Enable (level);
     288
    73289  return rc;
    74290}
     
    77293{
    78294  int c;
     295
    79296  while( kbd_first == kbd_last )
    80297  {
  • c/src/lib/libbsp/i386/pc386/console/keyboard.c

    r327a93a4 rd57c04e  
    6161int set_bit(int nr, unsigned long * addr)
    6262{
    63         int     mask, retval;
     63        int     mask, retval,level;
    6464
    6565        addr += nr >> 5;
    6666        mask = 1 << (nr & 0x1f);
    67         cli();
     67        _CPU_ISR_Disable(level)
    6868        retval = (mask & *addr) != 0;
    6969        *addr |= mask;
    70         sti();
     70        _CPU_ISR_Enable (level);
    7171        return retval;
    7272}
     
    7474int clear_bit(int nr, unsigned long * addr)
    7575{
    76         int     mask, retval;
     76        int     mask, retval,level;
    7777
    7878        addr += nr >> 5;
    7979        mask = 1 << (nr & 0x1f);
    80         cli();
     80        _CPU_ISR_Disable(level)
    8181        retval = (mask & *addr) != 0;
    8282        *addr &= ~mask;
    83         sti();
     83        _CPU_ISR_Enable (level);
    8484        return retval;
    8585}
  • c/src/lib/libbsp/i386/pc386/console/pc_keyb.c

    r327a93a4 rd57c04e  
    637637}
    638638
    639 
     639/*
    640640char BSP_wait_polled_input( void )
    641641{
    642   int c;
    643   cli();
     642  int c,level;
     643
     644  _CPU_ISR_Disable(level);
    644645  while ( ( c= kbd_wait_for_input() ) < 0 )
    645646      continue;
    646   sti();
     647  _CPU_ISR_Enable (level);
    647648  return c;
    648649}
     650*/
  • c/src/lib/libbsp/i386/pc386/console/vt.c

    r327a93a4 rd57c04e  
    6767_kd_mksound(unsigned int hz, unsigned int ticks)
    6868{
    69         unsigned int count = 0;
     69  unsigned int count = 0;
     70  int level;
    7071
    7172        if (hz > 20 && hz < 32767)
    7273                count = 1193180 / hz;
    7374       
    74         cli();
     75         _CPU_ISR_Disable(level);
    7576/*      del_timer(&sound_timer);  */
    7677        if (count) {
     
    9293                kd_nosound(0);
    9394
    94         sti();
     95         _CPU_ISR_Enable (level);
    9596        return;
    9697}
  • c/src/lib/libbsp/i386/pc386/include/bsp.h

    r327a93a4 rd57c04e  
    123123#define TIMER_16BIT    0x30            /* r/w counter 16 bits, LSB first */
    124124#define TIMER_BCD      0x01            /* count in BCD                   */
     125#define TIMER_RD_BACK  0xc0            /* Read Back Command              */
     126                /* READ BACK command layout in the Command Register      */
     127#define RB_NOT_COUNT    0x40           /* Don't select counter latch     */
     128#define RB_NOT_STATUS   0x20           /* Don't select status latch      */
     129#define RB_COUNT_0      0x02           /* Counter 0 latch                */
     130#define RB_COUNT_1      0x04           /* Counter 1 latch                */
     131#define RB_COUNT_2      0x08           /* Counter 2 latch                */
     132#define RB_OUTPUT       0x80           /* Output of the counter is 1     */
    125133
    126134#define TIMER_TICK     1193182  /* The internal tick rate in ticks per second */
  • c/src/lib/libbsp/i386/pc386/start/start.S

    r327a93a4 rd57c04e  
    146146        xorl    eax, eax                # value to clear out memory
    147147        repne                           # while ecx != 0
    148         stosl                           #   clear a long in the bss
    149 
     148        stosl
     149                                        #   clear a long in the bss
     150
     151/*-------------------------------------------------------------------+
     152| Initialize the video because zero_bss has cleared initVideo parameters
     153| if it was called earlier
     154| So from now we can use printk
     155+-------------------------------------------------------------------*/
     156        call _IBMPC_initVideo
     157               
    150158/*---------------------------------------------------------------------+
    151159| Check CPU type. Enable Cache and init coprocessor if needed.
    152160+---------------------------------------------------------------------*/
    153161        call checkCPUtypeSetCr0
     162       
    154163/*---------------------------------------------------------------------+
    155164| Transfer control to User's Board Support Package
  • c/src/lib/libbsp/i386/pc386/startup/bspstart.c

    r327a93a4 rd57c04e  
    139139{
    140140  void Calibrate_loop_1ms(void);
    141 
     141 
    142142  /*
    143143   * Calibrate variable for 1ms-loop (see timer.c)
    144144   */
    145145  Calibrate_loop_1ms();
    146 
    147   /*
    148    * Initialize printk channel
    149    */
    150  
    151   _IBMPC_initVideo();
    152146
    153147  rtemsFreeMemStart = (rtems_unsigned32)&_end + _stack_size;
  • c/src/lib/libbsp/i386/pc386/timer/timer.c

    r327a93a4 rd57c04e  
    6161+--------------------------------------------------------------------------*/
    6262volatile rtems_unsigned32 Ttimer_val;
    63          rtems_boolean    Timer_driver_Find_average_overhead = TRUE;
    64          unsigned int     loop1ms;
     63rtems_boolean             Timer_driver_Find_average_overhead = TRUE;
     64volatile unsigned int     fastLoop1ms, slowLoop1ms;
    6565
    6666/*-------------------------------------------------------------------------+
     
    306306} /* Set_find_average_overhead */
    307307
    308 
     308static unsigned short lastLoadedValue;
    309309
    310310/*-------------------------------------------------------------------------+
    311311| Description: Loads timer 0 with value passed as arguemnt.
    312 | Returns: Nothing.
    313 +--------------------------------------------------------------------------*/
    314 inline void loadTimerValue( unsigned short loadedValue )
    315 {
    316   outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
    317   outport_byte(TIMER_CNTR0, loadedValue >> 0 & 0xff);
    318   outport_byte(TIMER_CNTR0, loadedValue >> 8 & 0xff);
    319 }
    320 
    321 
    322 /*-------------------------------------------------------------------------+
    323 | Description: Waits until the counter on timer 0 reaches 0.
    324 | Returns: Nothing.
    325 +--------------------------------------------------------------------------*/
    326 inline void waitTimerStatus( void )
    327 {
    328   unsigned char status;
    329   outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS); /* read Status counter 0 */
    330   inport_byte(TIMER_CNTR0, status);
    331   while (status & MSK_NULL_COUNT){      /* wait for counter ready */   
    332     outport_byte(TIMER_MODE, CMD_READ_BACK_STATUS);
    333     inport_byte(TIMER_CNTR0, status);
    334   }
     312| Returns: Nothing. Loaded value must be a number of clock bits...
     313+--------------------------------------------------------------------------*/
     314void loadTimerValue( unsigned short loadedValue )
     315{
     316  lastLoadedValue = loadedValue;
     317  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_SQWAVE);
     318  outport_byte(TIMER_CNTR0, loadedValue & 0xff);
     319  outport_byte(TIMER_CNTR0, (loadedValue >> 8) & 0xff);
    335320}
    336321
     
    339324| Description: Reads the current value of the timer, and converts the
    340325|                          number of ticks to micro-seconds.   
    341 | Returns: current number of microseconds since last value loaded..
    342 +--------------------------------------------------------------------------*/
    343 inline unsigned short readCurrentTimer()
     326| Returns: number of clock bits elapsed since last load.
     327+--------------------------------------------------------------------------*/
     328unsigned int readTimer0()
    344329{
    345330  unsigned short lsb, msb;
    346   outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);
     331  unsigned char  status;
     332  unsigned int   count;
     333
     334  outport_byte(TIMER_MODE, (TIMER_RD_BACK | (RB_COUNT_0 & ~(RB_NOT_STATUS | RB_NOT_COUNT))));
     335  inport_byte(TIMER_CNTR0, status);
    347336  inport_byte(TIMER_CNTR0, lsb);
    348337  inport_byte(TIMER_CNTR0, msb);
    349   return TICK_TO_US( ( msb << 8 ) | lsb );
    350 }
    351 
    352 
    353 /*-------------------------------------------------------------------------+
    354  * clockbits - Read low order bits of timer 0 (the TOD clock)
    355  * This works only for the 8254 chips used in ATs and 386s.
    356  *
    357  * The timer runs in mode 3 (square wave mode), counting down
    358  * by twos, twice for each cycle. So it is necessary to read back the
    359  * OUTPUT pin to see which half of the cycle we're in. I.e., the OUTPUT
    360  * pin forms the most significant bit of the count. Unfortunately,
    361  * the 8253 in the PC/XT lacks a command to read the OUTPUT pin...
    362  *
    363  * The PC's clock design is soooo brain damaged...
    364  *
    365  * Rosimildo - I've got this routine from the KA9Q32 distribution and
    366  *                         have updated it for the RTEMS environment.
    367  +--------------------------------------------------------------------------*/
    368 unsigned int clockbits(void)
    369 {
    370         unsigned int stat,count1, count;
    371 
    372         do
    373         {
    374           outport_byte( 0x43, 0xc2 );    /* latch timer 0 count and status for reading */
    375           inport_byte( 0x40, stat );     /* get status of timer 0 */
    376           inport_byte( 0x40, count1 ); /* lsb of count */
    377           inport_byte( 0x40, count ); /* msb of count */
    378           count = count1 | ( count << 8 );
    379         } while(stat & 0x40);            /* reread if NULL COUNT bit set */
    380         stat = (stat & 0x80) << 8;       /* Shift OUTPUT to msb of 16-bit word */
    381         if(count == 0)
    382                 return stat ^ 0x8000;   /* return complement of OUTPUT bit */
    383         else
    384                 return count | stat;    /* Combine OUTPUT with counter */
    385 }
    386 
    387 
    388 /*-------------------------------------------------------------------------+
    389 |         Function: Calibrate_loop_1ms
    390 |      Description: Set loop variable to calibrate a 1ms loop
    391 | Global Variables: loop1ms
    392 |        Arguments: none
    393 |          Returns: Nothing.
    394 +--------------------------------------------------------------------------*/
     338  count = ( msb << 8 ) | lsb ;
     339  if (status & RB_OUTPUT )
     340        count += lastLoadedValue;
     341 
     342  return (2*lastLoadedValue - count);
     343}
     344
     345void Timer0Reset()
     346{
     347  loadTimerValue(0xffff);
     348  readTimer0();
     349}
     350
     351void fastLoop (unsigned int loopCount)
     352{
     353  unsigned int i;
     354  for( i=0; i < loopCount; i++ )outport_byte( SLOW_DOWN_IO, 0 );
     355}
     356
     357void slowLoop (unsigned int loopCount)
     358{
     359  unsigned int j;
     360  for (j=0; j <100 ;  j++) {
     361    fastLoop (loopCount);
     362  }
     363}
     364
     365/*
     366 * #define DEBUG_CALIBRATE
     367 */
    395368void
    396369Calibrate_loop_1ms(void)
    397370{
    398   unsigned int i;
    399   unsigned short loadedValue, offset;
    400   unsigned int timerValue, t1_ref, t2_ref=0;
     371  unsigned int offset, offsetTmp, emptyCall, emptyCallTmp, res, i, j;
     372  unsigned int targetClockBits, currentClockBits;
     373  unsigned int slowLoopGranularity, fastLoopGranularity;
    401374  rtems_interrupt_level  level;
    402375 
    403 
    404   printk( "Calibrate_loop_1ms is starting,  please wait ( but not too loooong. )\n" );
    405  
    406   loop1ms = 200;
    407   timerValue = 0;
    408 
    409   /* Let's load the timer with 2ms, initially */
    410   loadedValue = US_TO_TICK( 2000 );
     376#ifdef DEBUG_CALIBRATE
     377  printk( "Calibrate_loop_1ms is starting,  please wait ( but not too loooong. )\n" );
     378#endif 
     379  targetClockBits = US_TO_TICK(1000);
    411380 
    412381  rtems_interrupt_disable(level);
    413382  /*
    414    * Compute the offset to apply due to read counter register
     383   * Fill up the cache to get a correct offset
    415384   */
    416   offset = 0;
    417   loadTimerValue( loadedValue + offset );
    418   waitTimerStatus();
    419   t1_ref = clockbits();
    420   offset = loadedValue - readCurrentTimer();
    421   while( timerValue < 1000 )
    422   {
    423     loop1ms++;
    424     loadTimerValue( loadedValue + offset );
    425     waitTimerStatus();
    426     t1_ref = clockbits();
    427     for( i=0; i < loop1ms; i++ )
    428        outport_byte( SLOW_DOWN_IO, 0 ); /* write is # 1us */
    429     t2_ref = clockbits();
    430     timerValue = TICK_TO_US( t1_ref - t2_ref );  /* timer0 is decrementing number of ticks  */
    431   }
    432   printk( "Calibrate_loop_1ms timerValue=%d, loop1ms=%d, t1_ref=%x, clockbits=%x, delta=%d\n",
    433                    timerValue, loop1ms, t1_ref, t2_ref, t1_ref - t2_ref );
     385  Timer0Reset();
     386  readTimer0();
     387  /*
     388   * Compute the minimal offset to apply due to read counter register.
     389   */
     390  offset = 0xffffffff;
     391  for (i=0; i <1000; i++) {
     392    Timer0Reset();
     393    offsetTmp = readTimer0();
     394    offset += offsetTmp;
     395  }
     396  offset = offset / 1000; /* compute average */
     397  /*
     398   * calibrate empty call
     399   */
     400  fastLoop (0);
     401  emptyCall = 0;
     402  j = 0;
     403  for (i=0; i <10; i++) {
     404    Timer0Reset();
     405    fastLoop (0);
     406    res =  readTimer0();
     407    /* res may be inferior to offset on fast
     408     * machine because we took an average for offset
     409     */
     410    if (res >  offset) {
     411      ++j;
     412      emptyCallTmp = res - offset;
     413      emptyCall += emptyCallTmp;
     414    }
     415  }
     416  if (j == 0) emptyCall = 0;
     417  else emptyCall = emptyCall / j; /* compute average */
     418  /*
     419   * calibrate fast loop
     420   */
     421  Timer0Reset();
     422  fastLoop (10000);
     423  res = readTimer0() - offset;
     424  if (res < emptyCall) {
     425     printk("Problem #1 in offset computation in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");
     426    while (1);
     427  }
     428  fastLoopGranularity = (res - emptyCall) / 10000;
     429  /*
     430   * calibrate slow loop
     431   */
     432  Timer0Reset();
     433  slowLoop(10);
     434  res = readTimer0();
     435  if (res < offset + emptyCall) {
     436     printk("Problem #2 in offset computation in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");
     437    while (1);
     438  }
     439  slowLoopGranularity = (res - offset - emptyCall)/ 10;
     440 
     441  if (slowLoopGranularity == 0) {
     442    printk("Problem #3 in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");
     443    while (1);
     444  }
     445
     446  targetClockBits += offset;
     447#ifdef DEBUG_CALIBRATE 
     448  printk("offset = %u, emptyCall = %u, targetClockBits = %u\n",
     449         offset, emptyCall, targetClockBits);
     450  printk("slowLoopGranularity = %u fastLoopGranularity =  %u\n",
     451         slowLoopGranularity, fastLoopGranularity);
     452#endif 
     453  slowLoop1ms = (targetClockBits - emptyCall) / slowLoopGranularity;
     454  if (slowLoop1ms != 0) {
     455    fastLoop1ms = targetClockBits % slowLoopGranularity;
     456    if (fastLoop1ms > emptyCall) fastLoop1ms -= emptyCall;
     457  }   
     458  else
     459    fastLoop1ms = targetClockBits - emptyCall / fastLoopGranularity;
     460
     461  if (slowLoop1ms != 0) {
     462    /*
     463     * calibrate slow loop
     464     */
     465 
     466    while(1)
     467      {
     468        int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */
     469        Timer0Reset();
     470        slowLoop(slowLoop1ms);
     471        currentClockBits = readTimer0();
     472        if (currentClockBits > targetClockBits) {
     473          if ((currentClockBits - targetClockBits) < slowLoopGranularity) {
     474            /* decrement loop counter anyway to be sure slowLoop(slowLoop1ms) < targetClockBits */
     475            --slowLoop1ms;
     476            break;
     477          }
     478          else {
     479            --slowLoop1ms;
     480            if (slowLoop1ms == 0) break;
     481            if (previousSign == 0) previousSign = 2;
     482            if (previousSign == 1) break;
     483          }
     484        }
     485        else {
     486          if ((targetClockBits - currentClockBits) < slowLoopGranularity) {
     487            break;
     488          }
     489          else {
     490            ++slowLoop1ms;
     491            if (previousSign == 0) previousSign = 1;
     492            if (previousSign == 2) break;
     493          }
     494        }
     495      }
     496  }
     497  /*
     498   * calibrate fast loop
     499   */
     500 
     501  if (fastLoopGranularity != 0 ) {
     502    while(1) {
     503      int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */
     504      Timer0Reset();
     505      if (slowLoop1ms != 0) slowLoop(slowLoop1ms);
     506      fastLoop(fastLoop1ms);
     507      currentClockBits = readTimer0();
     508      if (currentClockBits > targetClockBits) {
     509        if ((currentClockBits - targetClockBits) < fastLoopGranularity)
     510          break;
     511        else {
     512          --fastLoop1ms;
     513          if (previousSign == 0) previousSign = 2;
     514          if (previousSign == 1) break;
     515        }
     516      }
     517      else {
     518        if ((targetClockBits - currentClockBits) < fastLoopGranularity)
     519          break;
     520        else {
     521          ++fastLoop1ms;
     522          if (previousSign == 0) previousSign = 1;
     523          if (previousSign == 2) break;
     524        }
     525      }
     526    }
     527  }
     528#ifdef DEBUG_CALIBRATE 
     529  printk("slowLoop1ms = %u, fastLoop1ms = %u\n", slowLoop1ms, fastLoop1ms);
     530#endif 
    434531  rtems_interrupt_enable(level);
    435 }
    436 
    437 
     532 
     533}
    438534
    439535/*-------------------------------------------------------------------------+
     
    447543Wait_X_ms( unsigned int timeToWait){
    448544
    449   unsigned int i, j;
    450 
    451   for (j=0; j<timeToWait ; j++)
    452     for (i=0; i<loop1ms; i++)
    453       outport_byte(SLOW_DOWN_IO, 0);    /* write is # 1us */
    454 }
    455 
    456 
    457 
    458 
    459 
    460 
     545  unsigned int j;
     546
     547  for (j=0; j<timeToWait ; j++) {
     548    if (slowLoop1ms != 0) slowLoop(slowLoop1ms);
     549    fastLoop(fastLoop1ms);
     550  }
     551
     552}
     553
     554
     555
     556
     557
     558
Note: See TracChangeset for help on using the changeset viewer.