|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2004 The KOS Team 002 Copyright (C) 1999 Free Software Foundation, Inc. 003 004 This program is free software; you can redistribute it and/or 005 modify it under the terms of the GNU General Public License 006 as published by the Free Software Foundation; either version 2 007 of the License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 017 USA. 018 */ 019 #include <hwcore/ioports.h> 020 021 #include "i8254.h" 022 023 /** 82c54 clock frequency */ 024 #define I8254_MAX_FREQ 1193180 025 026 /* Ports to communicate with the 82c54 */ 027 #define I8254_TIMER0 0x40 028 #define I8254_TIMER1 0x41 029 #define I8254_TIMER2 0x42 030 #define I8254_CONTROL 0x43 031 032 /** 033 * Configure the first timer of the 82c54 chip as a rate generator, 034 * which will raise an IRQ0 on a regular periodic basis, as given by 035 * the freq parameter. Second (RAM refresh) and third (speaker) timers 036 * are left unchanged. Maximum frequency is that of the 8254 clock, ie 037 * 1193180 Hz. 038 * 039 * Ahhh PC systems are nice toys: this maximum "strange" frequency 040 * equals that of the NTSC clock (14.31818 MHz) divided by 12. In 041 * turn, the famous 4.77 MHz cpu clock frequency of the first IBM PC 042 * is this same NTSC frequency divided by 3. Why the NTSC frequency as 043 * a base "standard" ? Because the 14.31818 MHz quartz were cheap at 044 * that time, and because it allows to simply drive altogether the 045 * cpu, the "time of day" timer, and the video signal generators. 046 */ 047 sos_ret_t sos_i8254_set_frequency(unsigned int freq) 048 { 049 unsigned int nb_tick; 050 051 if (freq <= 0) 052 return -SOS_EINVAL; 053 054 /* Compute counter value */ 055 nb_tick = I8254_MAX_FREQ / freq; 056 057 /* Counter must be between 1 and 65536 */ 058 if (nb_tick > 65536) 059 return -SOS_EINVAL; 060 if (nb_tick <= 0) 061 return -SOS_EINVAL; 062 063 /* The i8254 interprets 0 to mean counter == 65536, because 65536 064 cannot be coded on 16bits */ 065 if (nb_tick == 65536) 066 nb_tick = 0; 067 068 /* We want to configure timer0, we want to send both LSB+MSB to set 069 timer0 freq (-> 0x30), and we configure timer0 in mode 2, ie as a 070 rate generator (-> 0x4) ==> 0x34 */ 071 outb(0x34, I8254_CONTROL); 072 073 /* Send LSB of counter first */ 074 outb((nb_tick & 0xFF), I8254_TIMER0); 075 076 /* Send MSB of counter */ 077 outb((nb_tick >> 8) & 0xFF, I8254_TIMER0); 078 079 return SOS_OK; 080 }
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |