SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

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

source navigation ] diff markup ] identifier search ] general search ]