Changeset d57c04e in rtems
- Timestamp:
- 12/05/00 16:49:23 (23 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 57fe91f
- Parents:
- 327a93a4
- Location:
- c/src/lib/libbsp/i386/pc386
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/i386/pc386/ChangeLog
r327a93a4 rd57c04e 1 2000-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 1 14 2000-12-05 Joel Sherrill <joel@OARcorp.com> 2 15 -
c/src/lib/libbsp/i386/pc386/console/inch.c
r327a93a4 rd57c04e 37 37 | Constants 38 38 +--------------------------------------------------------------------------*/ 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 +--------------------------------------------------------------------------*/ 48 static 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 59 static 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 40 70 41 71 static unsigned short kbd_buffer[KBD_BUF_SIZE]; … … 58 88 59 89 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 +--------------------------------------------------------------------------*/ 100 static 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 +--------------------------------------------------------------------------*/ 223 static 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 +--------------------------------------------------------------------------*/ 250 char 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 265 char 266 BSP_wait_polled_input(void) 267 { 268 char c; 269 while (!_IBMPC_scankey(&c)) 270 continue; 271 272 return c; 273 } 274 63 275 /* 64 276 * Check if a key has been pressed. This is a non-destructive … … 67 279 int rtems_kbpoll( void ) 68 280 { 69 int rc; 70 disable; 281 int rc,level; 282 283 _CPU_ISR_Disable(level); 284 71 285 rc = ( kbd_first != kbd_last ) ? TRUE : FALSE; 72 enable; 286 287 _CPU_ISR_Enable (level); 288 73 289 return rc; 74 290 } … … 77 293 { 78 294 int c; 295 79 296 while( kbd_first == kbd_last ) 80 297 { -
c/src/lib/libbsp/i386/pc386/console/keyboard.c
r327a93a4 rd57c04e 61 61 int set_bit(int nr, unsigned long * addr) 62 62 { 63 int mask, retval ;63 int mask, retval,level; 64 64 65 65 addr += nr >> 5; 66 66 mask = 1 << (nr & 0x1f); 67 cli();67 _CPU_ISR_Disable(level) 68 68 retval = (mask & *addr) != 0; 69 69 *addr |= mask; 70 sti();70 _CPU_ISR_Enable (level); 71 71 return retval; 72 72 } … … 74 74 int clear_bit(int nr, unsigned long * addr) 75 75 { 76 int mask, retval ;76 int mask, retval,level; 77 77 78 78 addr += nr >> 5; 79 79 mask = 1 << (nr & 0x1f); 80 cli();80 _CPU_ISR_Disable(level) 81 81 retval = (mask & *addr) != 0; 82 82 *addr &= ~mask; 83 sti();83 _CPU_ISR_Enable (level); 84 84 return retval; 85 85 } -
c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
r327a93a4 rd57c04e 637 637 } 638 638 639 639 /* 640 640 char BSP_wait_polled_input( void ) 641 641 { 642 int c; 643 cli(); 642 int c,level; 643 644 _CPU_ISR_Disable(level); 644 645 while ( ( c= kbd_wait_for_input() ) < 0 ) 645 646 continue; 646 sti();647 _CPU_ISR_Enable (level); 647 648 return c; 648 649 } 650 */ -
c/src/lib/libbsp/i386/pc386/console/vt.c
r327a93a4 rd57c04e 67 67 _kd_mksound(unsigned int hz, unsigned int ticks) 68 68 { 69 unsigned int count = 0; 69 unsigned int count = 0; 70 int level; 70 71 71 72 if (hz > 20 && hz < 32767) 72 73 count = 1193180 / hz; 73 74 74 cli();75 _CPU_ISR_Disable(level); 75 76 /* del_timer(&sound_timer); */ 76 77 if (count) { … … 92 93 kd_nosound(0); 93 94 94 sti();95 _CPU_ISR_Enable (level); 95 96 return; 96 97 } -
c/src/lib/libbsp/i386/pc386/include/bsp.h
r327a93a4 rd57c04e 123 123 #define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ 124 124 #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 */ 125 133 126 134 #define TIMER_TICK 1193182 /* The internal tick rate in ticks per second */ -
c/src/lib/libbsp/i386/pc386/start/start.S
r327a93a4 rd57c04e 146 146 xorl eax, eax # value to clear out memory 147 147 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 150 158 /*---------------------------------------------------------------------+ 151 159 | Check CPU type. Enable Cache and init coprocessor if needed. 152 160 +---------------------------------------------------------------------*/ 153 161 call checkCPUtypeSetCr0 162 154 163 /*---------------------------------------------------------------------+ 155 164 | Transfer control to User's Board Support Package -
c/src/lib/libbsp/i386/pc386/startup/bspstart.c
r327a93a4 rd57c04e 139 139 { 140 140 void Calibrate_loop_1ms(void); 141 141 142 142 /* 143 143 * Calibrate variable for 1ms-loop (see timer.c) 144 144 */ 145 145 Calibrate_loop_1ms(); 146 147 /*148 * Initialize printk channel149 */150 151 _IBMPC_initVideo();152 146 153 147 rtemsFreeMemStart = (rtems_unsigned32)&_end + _stack_size; -
c/src/lib/libbsp/i386/pc386/timer/timer.c
r327a93a4 rd57c04e 61 61 +--------------------------------------------------------------------------*/ 62 62 volatile rtems_unsigned32 Ttimer_val; 63 rtems_booleanTimer_driver_Find_average_overhead = TRUE;64 unsigned int loop1ms;63 rtems_boolean Timer_driver_Find_average_overhead = TRUE; 64 volatile unsigned int fastLoop1ms, slowLoop1ms; 65 65 66 66 /*-------------------------------------------------------------------------+ … … 306 306 } /* Set_find_average_overhead */ 307 307 308 308 static unsigned short lastLoadedValue; 309 309 310 310 /*-------------------------------------------------------------------------+ 311 311 | 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 +--------------------------------------------------------------------------*/ 314 void 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); 335 320 } 336 321 … … 339 324 | Description: Reads the current value of the timer, and converts the 340 325 | 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 +--------------------------------------------------------------------------*/ 328 unsigned int readTimer0() 344 329 { 345 330 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); 347 336 inport_byte(TIMER_CNTR0, lsb); 348 337 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 345 void Timer0Reset() 346 { 347 loadTimerValue(0xffff); 348 readTimer0(); 349 } 350 351 void fastLoop (unsigned int loopCount) 352 { 353 unsigned int i; 354 for( i=0; i < loopCount; i++ )outport_byte( SLOW_DOWN_IO, 0 ); 355 } 356 357 void 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 */ 395 368 void 396 369 Calibrate_loop_1ms(void) 397 370 { 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; 401 374 rtems_interrupt_level level; 402 375 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); 411 380 412 381 rtems_interrupt_disable(level); 413 382 /* 414 * Compute the offset to apply due to read counter register383 * Fill up the cache to get a correct offset 415 384 */ 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 434 531 rtems_interrupt_enable(level); 435 } 436 437 532 533 } 438 534 439 535 /*-------------------------------------------------------------------------+ … … 447 543 Wait_X_ms( unsigned int timeToWait){ 448 544 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.