## Connect to USB host and receive a reset

Being able to blink LEDs and measure time is nice and all, but we won’t
get very far that way. Of course, three LEDs are enough to display three
bits of information; by blinking them, we can transmit an unlimited
amount of data. But they won’t be human-readable. Even reading an 8-bit
key index would be hard if it were encoded as 8 flashes.

So we want to be a proper USB device implementing the Human Interface
Device protocol.

The base [USB specification][USB20] is a hefty 650-page tome; the [HID
class spec][HID111] adds 97 pages, not counting the [HID Usage
Tables][HUT112]. Luckily, there are [tutorials][] about implementing USB
devices…

[USB20]: http://www.usb.org/developers/docs/usb20_docs/
[HID111]: http://www.usb.org/developers/hidpage#Class_Definitions
[HUT112]: http://www.usb.org/developers/hidpage#HID_Usage
[tutorials]: http://www.usbmadesimple.co.uk/index.html

First we need to enable the USB functionality in the MG84FL54. The SDK
manual tells us the steps: we set `EN_PLL` in `CKCON2`, wait till
`PLL_RDY` in `CKCON2` becomes set, wait 2ms, and set `EN_USB` in
`CKCON2`. We also need to set `CONEN` in the `UPCON` register to connect
to the host.

After that, the host will send us a USB reset. We receive it by means of
a USB interrupt from the `URST` line. This means we have to have
interrupts enabled (`EA`, already set since our timer exercise), we need
to enable the USB interrupt (`EUSB` in `AUXIE`), and tell that we want
USB interrupts for reset/resume/suspend events (`EFSR` in `IEN`).

The interrupt handler will just check that the `URST` flag is set,
acknowledge it, and light the Caps LED. Otherwise, light the Num LED.
This way we can test that our assumptions are correct.