■ FIGURE 3. The device implements
just volume and mute but if you are
adventurous, you can hack the
supplied source code to implement
the other media controls shown.
host know that a full speed device has attached and
causes a sequence of events to occur called enumeration.
During enumeration, the host reads the contents of the
descriptor. Once enumeration is complete, the device is
configured and ready to send data to the host. To move
data, the USB standards specify that HID devices use the
Interrupt Transfer protocol.
■ FIGURE 4.
length. Each bit — called a usage in USB language —
defines a particular media control. The layout of the report
is shown in Figure 3. I only needed to control the volume
and mute functions for this project but if you want to
experiment with the software provided, you can change
the source code to control the other usages.
The media usages function likes push on/push off
buttons. For example, to toggle mute on, the device’s
firmware needs to send a “1” in bit location 0 to the host.
The device must then send a “0” in that bit position to
reset the toggle because the usages are triggered on the 0
to 1 transition.
When the device is plugged into a USB port, it
receives power, resets, and runs through its initialization
routine. The device then connects an internal resistor (1.5
KW) from the D+ line to the internal 3.3V regulator,
creating a voltage change on the D+ line. This lets the
All USB devices operate on the same basic principle:
The host makes a request for data and the device
responds. So, how does the device signal the host when it
has data available? The type of data transfer used by HID
devices is called an interrupt transfer, but this is
misleading. There is no mechanism for the device to call
the host when it has data ready. To receive reports from
the device, the host makes periodic requests for data — in
our device, every 10 milliseconds — called a “polling
interval.” When the device has data ready to send to the
host, the device loads its data into a special memory
location called an endpoint. During each polling interval,
the host asks the device to send the data in the endpoint.
If the device has no data to send, it responds with a Zero
Length Packet (ZLP) instead.
Mechanical switches require contact debouncing to
prevent false signals. Figure 4 shows an
example oscilloscope capture of what the
microcontroller sees when the mute button is
pressed. The encoder switches have a similar
contact bounce characteristic. The strategy is
to wait until the switch has stabilized after
the first closure has been detected, and I
decided to implement debouncing in
software. A hardware solution was possible
but would have meant more components.
Debouncing is handled using one of the
AT90USB162’s built-in timers to sample the
switch input pins periodically. The encoder
and the mute pushbutton require separate
debouncing algorithms due to their different
characteristics. Debouncing the pushbutton is
simple. A software routine uses an eight-bit
shift register to accumulate a sample from the
PART ID NAME PACKAGE Digi-Key PART#
R1 470 ohm, 1% 0806 RC0805FR-07470RL
R2,R3 22.0 ohm, 1% 0806 RC0805FR-0722RL
C1,C4 0.1 µF/16V 0806 GRM219R71C104KA01D
C2,C3 18 pF/50V 0806 500R15N180JV4T
C5 1.0 µF/16V 0806 TCP1C105M8R
C6 10 µF/16V Through-hole 199D106X9016C6V1E3
U1 AT90USB162 32 TQFP AT90USB162-16AU
Y1 16 MHz crystal 49US ECS-160-20-4VX
D1 LED hi eff blue 3 mm TLHB4400
S1/S3a/S3b Encoder with switch Panel mount 288V232R161B2
S2 Reset Tactile EG1829
Box Enclosure Aluminum 1590LLB
Knob Knob for encoder Aluminum 450-1712-ND
Cable USB cable Round, 3' 3021005-03