CS318 - Pintos
Pintos source browser for JHU CS318 course
speaker.c
Go to the documentation of this file.
1 #include "devices/speaker.h"
2 #include "devices/pit.h"
3 #include "threads/io.h"
4 #include "threads/interrupt.h"
5 #include "devices/timer.h"
6 
7 /** Speaker port enable I/O register. */
8 #define SPEAKER_PORT_GATE 0x61
9 
10 /** Speaker port enable bits. */
11 #define SPEAKER_GATE_ENABLE 0x03
12 
13 /** Sets the PC speaker to emit a tone at the given FREQUENCY, in
14  Hz. */
15 void
16 speaker_on (int frequency)
17 {
18  if (frequency >= 20 && frequency <= 20000)
19  {
20  /* Set the timer channel that's connected to the speaker to
21  output a square wave at the given FREQUENCY, then
22  connect the timer channel output to the speaker. */
23  enum intr_level old_level = intr_disable ();
24  pit_configure_channel (2, 3, frequency);
26  intr_set_level (old_level);
27  }
28  else
29  {
30  /* FREQUENCY is outside the range of normal human hearing.
31  Just turn off the speaker. */
32  speaker_off ();
33  }
34 }
35 
36 /** Turn off the PC speaker, by disconnecting the timer channel's
37  output from the speaker. */
38 void
40 {
41  enum intr_level old_level = intr_disable ();
43  intr_set_level (old_level);
44 }
45 
46 /** Briefly beep the PC speaker. */
47 void
49 {
50  /* Only attempt to beep the speaker if interrupts are enabled,
51  because we don't want to freeze the machine during the beep.
52  We could add a hook to the timer interrupt to avoid that
53  problem, but then we'd risk failing to ever stop the beep if
54  Pintos crashes for some unrelated reason. There's nothing
55  more annoying than a machine whose beeping you can't stop
56  without a power cycle.
57 
58  We can't just enable interrupts while we sleep. For one
59  thing, we get called (indirectly) from printf, which should
60  always work, even during boot before we're ready to enable
61  interrupts. */
62  if (intr_get_level () == INTR_ON)
63  {
64  speaker_on (440);
65  timer_msleep (250);
66  speaker_off ();
67  }
68 }
timer_msleep
void timer_msleep(int64_t ms)
Sleeps for approximately MS milliseconds.
Definition: timer.c:102
speaker_on
void speaker_on(int frequency)
Sets the PC speaker to emit a tone at the given FREQUENCY, in Hz.
Definition: speaker.c:16
SPEAKER_GATE_ENABLE
#define SPEAKER_GATE_ENABLE
Speaker port enable bits.
Definition: speaker.c:11
intr_level
intr_level
Interrupts on or off?
Definition: interrupt.h:8
speaker.h
intr_set_level
enum intr_level intr_set_level(enum intr_level level)
Enables or disables interrupts as specified by LEVEL and returns the previous interrupt status.
Definition: interrupt.c:81
speaker_beep
void speaker_beep(void)
Briefly beep the PC speaker.
Definition: speaker.c:48
pit.h
interrupt.h
pit_configure_channel
void pit_configure_channel(int channel, int mode, int frequency)
Configure the given CHANNEL in the PIT.
Definition: pit.c:46
intr_get_level
enum intr_level intr_get_level(void)
Returns the current interrupt status.
Definition: interrupt.c:65
timer.h
intr_disable
enum intr_level intr_disable(void)
Disables interrupts and returns the previous interrupt status.
Definition: interrupt.c:104
outb
static void outb(uint16_t port, uint8_t data)
Writes byte DATA to PORT.
Definition: io.h:66
speaker_off
void speaker_off(void)
Turn off the PC speaker, by disconnecting the timer channel's output from the speaker.
Definition: speaker.c:39
inb
static uint8_t inb(uint16_t port)
Reads and returns a byte from PORT.
Definition: io.h:9
io.h
SPEAKER_PORT_GATE
#define SPEAKER_PORT_GATE
Speaker port enable I/O register.
Definition: speaker.c:8
INTR_ON
Interrupts enabled.
Definition: interrupt.h:11