summaryrefslogtreecommitdiffstats
path: root/app/consumer.c
blob: b1b62908e9d56bc25b297ec7af4be4f0dc320488 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "project.h"


static const uint8_t consumer_report_descriptor[] = {
  0x05, 0x0c,                   /* Usage Page (Consumer Devices) */
  0x09, 0x01,                   /* Usage (Consumer Control) */
  0xA1, 0x01,                   /* Collection (Application) */
  0x15, 0x00,                   /*     Logical minimum (0) */
  0x25, 0x01,                   /*     Logical maximum (1) */
  0x75, 0x01,                   /*     Report size (1) */
  0x95, 0x10,                   /*     Report count (16) */

  0x09, 0xb5,                   /*     USAGE (Scan Next Track) */
  0x09, 0xb6,                   /*     USAGE (Scan Prev Track) */
  0x09, 0xb7,                   /*     USAGE (Stop) */
  0x09, 0xcd,                   /*     USAGE (Play/Pause) */

  0x09, 0xe2,                   /*     USAGE (Mute) */
  0x09, 0xe9,                   /*     USAGE (Volume up) */
  0x09, 0xea,                   /*     USAGE (Volume down) */
  0x0a, 0x21, 0x02,             /*     USAGE (www search) */

  0x0a, 0x23, 0x02,             /*     USAGE (www home) */
  0x0a, 0x24, 0x02,             /*     USAGE (www back) */
  0x0a, 0x25, 0x02,             /*     USAGE (www forward) */
  0x0a, 0x26, 0x02,             /*     USAGE (www stop) */

  0x0a, 0x27, 0x02,             /*     USAGE (www refresh) */
  0x0a, 0x2a, 0x02,             /*     USAGE (www favourites) */
  0x0a, 0x8a, 0x01,             /*     USAGE (Mail) */
  0x0a, 0x92, 0x01,             /*     USAGE (Calculator) */

  0x81, 0x62,                   /*     Input (data, variable, relative, preferreed) */
  0xC0                          /* End Collection */
};


static const struct
{
  struct usb_hid_descriptor hid_descriptor;
  struct
  {
    uint8_t bReportDescriptorType;
    uint16_t wDescriptorLength;
  } __attribute__ ((packed)) hid_report;
} __attribute__ ((packed)) consumer_function =
{
  .hid_descriptor =
  {
  .bLength = sizeof (consumer_function),.bDescriptorType =
      USB_DT_HID,.bcdHID = 0x0100,.bCountryCode = 0,.bNumDescriptors = 1,}
  ,.hid_report =
  {
  .bReportDescriptorType = USB_DT_REPORT,.wDescriptorLength =
      sizeof (consumer_report_descriptor),}
,};

const struct usb_endpoint_descriptor consumer_endpoint = {
  .bLength = USB_DT_ENDPOINT_SIZE,
  .bDescriptorType = USB_DT_ENDPOINT,
  .bEndpointAddress = CONSUMER_EP,
  .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
  .wMaxPacketSize = 2,
  .bInterval = 0x1              //0x20,
};

const struct usb_interface_descriptor consumer_iface = {
  .bLength = USB_DT_INTERFACE_SIZE,
  .bDescriptorType = USB_DT_INTERFACE,
  .bInterfaceNumber = 1,
  .bAlternateSetting = 0,
  .bNumEndpoints = 1,
  .bInterfaceClass = USB_CLASS_HID,
  .bInterfaceSubClass = 1,      /* boot */
  .bInterfaceProtocol = 1,      /* consumer */
  .iInterface = 6,

  .endpoint = &consumer_endpoint,

  .extra = &consumer_function,
  .extralen = sizeof (consumer_function),
};


void
consumer_get_descriptor (uint8_t ** buf, uint16_t * len)
{

  /* Handle the HID report descriptor. */
  *buf = (uint8_t *) consumer_report_descriptor;
  *len = sizeof (consumer_report_descriptor);
}



static void
consumer_send (uint16_t keys)
{
  /*Last byte is the power wakeup stuff that we don't yet support */
  uint8_t buf[CONSUMER_EP_TXN_SIZE] = { keys & 0xff, keys >> 8 };

  if (!usb_is_suspended)
    usbd_ep_write_packet (usbd_dev, CONSUMER_EP, buf, sizeof (buf));
}

static uint16_t keys;

void
consumer_dispatch (int bit, int updown)
{

  if (updown)
    keys |= bit;
  else
    keys &= ~bit;


#ifdef DEBUG
  printf ("CNS> %02x %02x\r\n", keys & 0xff, keys >> 8);
#endif

  usb_wakeup_host();

  consumer_send (keys);
}

void
consumer_error (void)
{
  keys = 0;
  consumer_send (keys);
}