annotate Bootloader/usb.c @ 308:ab4515606277

Fix whitespace Use a consistent standard - Tabs in front for indenting, spaces after for anything else. This way everything stays nice and lined up while also letting users change there prefered indent level. Most of the new files from Haata where already in this format.
author Rowan Decker <Smasher816@gmail.com>
date Sun, 08 Mar 2015 18:40:01 -0700
parents b091bb09c55f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
193
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
1 /* Copyright (c) 2011,2012 Simon Schubert <2@0x2c.org>.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
2 * Modifications by Jacob Alexander 2014 <haata@kiibohd.com>
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
3 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
4 * This program is free software: you can redistribute it and/or modify
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
6 * the Free Software Foundation, either version 3 of the License, or
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
7 * (at your option) any later version.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
8 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
9 * This program is distributed in the hope that it will be useful,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
12 * GNU General Public License for more details.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
13 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
14 * You should have received a copy of the GNU General Public License
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
16 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
17
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
18 // ----- Compiler Includes -----
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
19
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
20 #include <sys/types.h>
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
21 #include <inttypes.h>
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
22 #include <string.h>
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
23
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
24
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
25 // ----- Local Includes -----
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
26
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
27 #include "usb.h"
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
28 #include "usb-internal.h"
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
29
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
30
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
31
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
32 // ----- Variables -----
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
33
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
34 static uint8_t ep0_buf[2][EP0_BUFSIZE] __attribute__((aligned(4)));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
35 struct usbd_t usb;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
36
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
37
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
38
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
39 // ----- Functions -----
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
40
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
41 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
42 * Returns: 0 when this is was the last transfer, 1 if there is still
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
43 * more to go.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
44 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
45 /* Defaults to EP0 for now */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
46 static int usb_tx_next(struct usbd_ep_pipe_state_t *s)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
47 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
48
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
49 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
50 * Us being here means the previous transfer just completed
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
51 * successfully. That means the host just toggled its data
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
52 * sync bit, and so do we.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
53 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
54 s->data01 ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
55
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
56 if (s->transfer_size > 0) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
57 size_t thislen = s->transfer_size;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
58
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
59 if (thislen > s->ep_maxsize)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
60 thislen = s->ep_maxsize;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
61
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
62 void *addr = s->data_buf + s->pos;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
63
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
64 if (s->copy_source) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
65 /* Bounce buffer mode */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
66 addr = s->data_buf;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
67 memcpy(addr, s->copy_source + s->pos, thislen);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
68 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
69 s->pos += thislen;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
70 s->transfer_size -= thislen;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
71
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
72 usb_queue_next(s, addr, thislen);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
73 s->pingpong ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
74
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
75 return (1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
76 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
77
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
78 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
79 * All data has been shipped. Do we need to send a short
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
80 * packet?
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
81 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
82 if (s->short_transfer) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
83 s->short_transfer = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
84 usb_queue_next(s, NULL, 0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
85 s->pingpong ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
86 return (1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
87 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
88
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
89 if (s->callback)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
90 s->callback(s->data_buf, s->pos, s->callback_data);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
91
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
92 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
93 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
94
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
95 static void setup_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
96 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
97 s->data_buf = (void *)buf;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
98 s->copy_source = NULL;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
99 s->transfer_size = len;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
100 s->pos = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
101 s->callback = cb;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
102 s->callback_data = cb_data;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
103 if (s->transfer_size > reqlen)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
104 s->transfer_size = reqlen;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
105 if (s->transfer_size < reqlen && s->transfer_size % s->ep_maxsize == 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
106 s->short_transfer = 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
107 else
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
108 s->short_transfer = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
109 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
110
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
111 static void submit_tx(struct usbd_ep_pipe_state_t *s)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
112 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
113 /* usb_tx_next() flips the data toggle, so invert this here. */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
114 s->data01 ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
115 usb_tx_next(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
116 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
117
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
118 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
119 * send USB data (IN device transaction)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
120 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
121 * So far this function is specialized for EP 0 only.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
122 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
123 * Returns: size to be transfered, or -1 on error.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
124 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
125 int usb_tx(struct usbd_ep_pipe_state_t *s, const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
126 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
127 setup_tx(s, buf, len, reqlen, cb, cb_data);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
128 submit_tx(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
129 return (s->transfer_size);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
130 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
131
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
132
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
133 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
134 * Returns: 0 when this is was the last transfer, 1 if there is still
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
135 * more to go.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
136 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
137 /* Defaults to EP0 for now */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
138 /* XXX pass usb_stat to validate pingpong */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
139 static int usb_rx_next(struct usbd_ep_pipe_state_t *s)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
140 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
141 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
142 * Us being here means the previous transfer just completed
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
143 * successfully. That means the host just toggled its data
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
144 * sync bit, and so do we.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
145 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
146 s->data01 ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
147
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
148 size_t thislen = usb_ep_get_transfer_size(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
149
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
150 s->transfer_size -= thislen;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
151 s->pos += thislen;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
152
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
153 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
154 * We're done with this buffer now. Switch the pingpong now
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
155 * before we might have to receive the next piece of data.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
156 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
157 s->pingpong ^= 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
158
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
159 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
160 * If this is a short transfer, or we received what we
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
161 * expected, we're done.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
162 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
163 if (thislen < s->ep_maxsize || s->transfer_size == 0) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
164 if (s->callback)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
165 s->callback(s->data_buf, s->pos, s->callback_data);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
166 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
167 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
168
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
169 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
170 * Otherwise we still need to receive more data.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
171 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
172 size_t nextlen = s->transfer_size;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
173
308
ab4515606277 Fix whitespace
Rowan Decker <Smasher816@gmail.com>
parents: 193
diff changeset
174 if (nextlen > s->ep_maxsize)
ab4515606277 Fix whitespace
Rowan Decker <Smasher816@gmail.com>
parents: 193
diff changeset
175 nextlen = s->ep_maxsize;
193
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
176
308
ab4515606277 Fix whitespace
Rowan Decker <Smasher816@gmail.com>
parents: 193
diff changeset
177 void *addr = s->data_buf + s->pos;
193
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
178 usb_queue_next(s, addr, nextlen);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
179
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
180 return (1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
181 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
182
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
183 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
184 * Receive USB data (OUT device transaction)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
185 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
186 * Returns: size to be received, or -1 on error.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
187 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
188 int usb_rx(struct usbd_ep_pipe_state_t *s, void *buf, size_t len, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
189 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
190 s->data_buf = buf;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
191 s->transfer_size = len;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
192 s->pos = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
193 s->callback = cb;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
194 s->callback_data = cb_data;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
195
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
196 size_t thislen = s->transfer_size;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
197 if (thislen > s->ep_maxsize)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
198 thislen = s->ep_maxsize;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
199
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
200 usb_queue_next(s, s->data_buf, thislen);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
201 return (len);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
202 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
203
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
204 int usb_ep0_tx_cp(const void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
205 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
206 struct usbd_ep_pipe_state_t *s = &usb.ep_state[0].tx;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
207 enum usb_ep_pingpong pp = s->pingpong;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
208
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
209 setup_tx(s, ep0_buf[pp], len, reqlen, cb, cb_data);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
210 s->copy_source = buf;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
211 submit_tx(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
212 return (s->transfer_size);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
213 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
214
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
215 void *usb_ep0_tx_inplace_prepare(size_t len)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
216 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
217 enum usb_ep_pingpong pp = usb.ep_state[0].tx.pingpong;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
218
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
219 if (len > EP0_BUFSIZE)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
220 return (NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
221
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
222 return (ep0_buf[pp]);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
223 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
224
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
225 int usb_ep0_tx(void *buf, size_t len, size_t reqlen, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
226 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
227 return (usb_tx(&usb.ep_state[0].tx, buf, len, reqlen, cb, cb_data));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
228 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
229
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
230 int usb_ep0_rx(void *buf, size_t len, ep_callback_t cb, void *cb_data)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
231 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
232 return (usb_rx(&usb.ep_state[0].rx, buf, len, cb, cb_data));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
233 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
234
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
235
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
236 const struct usbd_config *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
237 usb_get_config_data(int config)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
238 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
239 if (config <= 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
240 config = usb.config;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
241
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
242 if (config != 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
243 return (usb.identity->configs[config - 1]);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
244 else
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
245 return (NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
246 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
247
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
248 static int usb_set_config(int config)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
249 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
250 const struct usbd_config *config_data;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
251
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
252 if (usb.config != 0) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
253 config_data = usb_get_config_data(-1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
254 if (config_data != NULL && config_data->init != NULL)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
255 config_data->init(0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
256 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
257
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
258 if (config != 0) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
259 /* XXX overflow */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
260 config_data = usb_get_config_data(config);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
261 if (config_data != NULL && config_data->init != NULL)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
262 config_data->init(1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
263 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
264 usb.config = config;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
265 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
266 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
267
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
268 static int usb_set_interface(int iface, int altsetting)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
269 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
270 int iface_count = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
271
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
272 for (struct usbd_function_ctx_header *fh = &usb.functions;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
273 fh != NULL;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
274 fh = fh->next, iface_count += fh->function->interface_count) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
275 if (iface - iface_count < fh->function->interface_count) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
276 if (fh->function->configure != NULL)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
277 return (fh->function->configure(iface,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
278 iface - iface_count,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
279 altsetting,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
280 fh));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
281
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
282 /* Default to a single altsetting */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
283 if (altsetting != 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
284 return (-1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
285 else
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
286 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
287 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
288 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
289
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
290 return (-1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
291 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
292
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
293 static int usb_tx_config_desc(int idx, int reqlen)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
294 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
295 const struct usb_desc_config_t *d = usb.identity->configs[idx]->desc;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
296
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
297 usb_ep0_tx_cp(d, d->wTotalLength, reqlen, NULL, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
298 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
299 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
300
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
301 static int usb_tx_string_desc(int idx, int reqlen)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
302 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
303 const struct usb_desc_string_t * const *d;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
304
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
305 for (d = usb.identity->string_descs; idx != 0 && *d != NULL; ++d)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
306 --idx;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
307 switch ((uintptr_t)*d) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
308 case (uintptr_t)NULL:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
309 return (-1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
310 case (uintptr_t)USB_DESC_STRING_SERIALNO:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
311 return (usb_tx_serialno(reqlen));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
312 default:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
313 usb_ep0_tx_cp(*d, (*d)->bLength, reqlen, NULL, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
314 return (0);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
315 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
316 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
317
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
318
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
319 static void usb_handle_control_done(void *data, ssize_t len, void *cbdata)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
320 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
321 if (usb.state == USBD_STATE_SETTING_ADDRESS) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
322 usb.state = USBD_STATE_ADDRESS;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
323 usb_set_addr(usb.address);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
324 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
325 usb_setup_control();
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
326 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
327
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
328 void usb_handle_control_status_cb(ep_callback_t cb)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
329 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
330 /* empty status transfer */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
331 switch (usb.ctrl_dir) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
332 case USB_CTRL_REQ_IN:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
333 usb.ep_state[0].rx.data01 = USB_DATA01_DATA1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
334 usb_rx(&usb.ep_state[0].rx, NULL, 0, cb, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
335 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
336
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
337 default:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
338 usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
339 usb_ep0_tx_cp(NULL, 0, 1 /* short packet */, cb, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
340 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
341 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
342 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
343
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
344 void usb_handle_control_status(int fail)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
345 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
346 if (fail) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
347 usb_pipe_stall(&usb.ep_state[0].rx);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
348 usb_pipe_stall(&usb.ep_state[0].tx);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
349 } else {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
350 usb_handle_control_status_cb(usb_handle_control_done);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
351 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
352 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
353
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
354
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
355 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
356 * Dispatch non-standard request to registered USB functions.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
357 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
358 static void usb_handle_control_nonstd(struct usb_ctrl_req_t *req)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
359 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
360 /* XXX filter by interface/endpoint? */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
361 for (struct usbd_function_ctx_header *fh = &usb.functions; fh != NULL; fh = fh->next) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
362 /* ->control() returns != 0 if it handled the request */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
363 if (fh->function->control != NULL &&
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
364 fh->function->control(req, fh))
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
365 return;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
366 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
367
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
368 usb_handle_control_status(-1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
369 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
370
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
371
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
372 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
373 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
374 * Great resource: http://wiki.osdev.org/Universal_Serial_Bus
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
375 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
376 * Control Transfers
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
377 * -----------------
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
378 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
379 * A control transfer consists of a SETUP transaction (1), zero or
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
380 * more data transactions (IN or OUT) (2), and a final status
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
381 * transaction (3).
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
382 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
383 * Token sequence (data toggle):
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
384 * 1. SETUP (0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
385 * (2a. OUT (1) ... (toggling))
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
386 * 3a. IN (1)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
387 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
388 * or
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
389 * 1. SETUP (0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
390 * 2b. IN (1) ... (toggling)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
391 * 3b. OUT (1)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
392 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
393 * Report errors by STALLing the control EP after (1) or (2), so that
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
394 * (3) will STALL. Seems we need to clear the STALL after that so
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
395 * that the next SETUP can make it through.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
396 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
397 *
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
398 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
399
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
400 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
401 * The following code is not written defensively, but instead only
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
402 * asserts values that are essential for correct execution. It
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
403 * accepts a superset of the protocol defined by the standard. We do
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
404 * this to save space.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
405 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
406
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
407 static void usb_handle_control(void *data, ssize_t len, void *cbdata)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
408 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
409 struct usb_ctrl_req_t *req = data;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
410 uint16_t zero16 = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
411 int fail = 1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
412
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
413 usb.ctrl_dir = req->in;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
414
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
415 if (req->type != USB_CTRL_REQ_STD) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
416 usb_handle_control_nonstd(req);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
417 return;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
418 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
419
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
420 /* Only STD requests here */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
421 switch (req->bRequest) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
422 case USB_CTRL_REQ_GET_STATUS:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
423 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
424 * Because we don't support remote wakeup or
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
425 * self-powered operation, and we are specialized to
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
426 * only EP 0 so far, all GET_STATUS replies are just
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
427 * empty.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
428 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
429 usb_ep0_tx_cp(&zero16, sizeof(zero16), req->wLength, NULL, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
430 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
431
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
432 case USB_CTRL_REQ_CLEAR_FEATURE:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
433 case USB_CTRL_REQ_SET_FEATURE:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
434 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
435 * Nothing to do. Maybe return STALLs on illegal
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
436 * accesses?
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
437 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
438 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
439
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
440 case USB_CTRL_REQ_SET_ADDRESS:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
441 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
442 * We must keep our previous address until the end of
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
443 * the status stage; therefore we can't set the
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
444 * address right now. Since this is a special case,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
445 * the EP 0 handler will take care of this later on.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
446 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
447 usb.address = req->wValue & 0x7f;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
448 usb.state = USBD_STATE_SETTING_ADDRESS;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
449 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
450
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
451 case USB_CTRL_REQ_GET_DESCRIPTOR:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
452 switch (req->wValue >> 8) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
453 case USB_DESC_DEV:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
454 usb_ep0_tx_cp(usb.identity->dev_desc, usb.identity->dev_desc->bLength,
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
455 req->wLength, NULL, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
456 fail = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
457 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
458 case USB_DESC_CONFIG:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
459 fail = usb_tx_config_desc(req->wValue & 0xff, req->wLength);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
460 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
461 case USB_DESC_STRING:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
462 fail = usb_tx_string_desc(req->wValue & 0xff, req->wLength);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
463 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
464 default:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
465 fail = -1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
466 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
467 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
468 /* we set fail already, so we can go directly to `err' */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
469 goto err;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
470
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
471 case USB_CTRL_REQ_GET_CONFIGURATION:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
472 usb_ep0_tx_cp(&usb.config, 1, req->wLength, NULL, NULL); /* XXX implicit LE */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
473 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
474
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
475 case USB_CTRL_REQ_SET_CONFIGURATION:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
476 if (usb_set_config(req->wValue) < 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
477 goto err;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
478 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
479
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
480 case USB_CTRL_REQ_GET_INTERFACE:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
481 /* We only support iface setting 0 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
482 usb_ep0_tx_cp(&zero16, 1, req->wLength, NULL, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
483 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
484
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
485 case USB_CTRL_REQ_SET_INTERFACE:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
486 if (usb_set_interface(req->wIndex, req->wValue) < 0)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
487 goto err;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
488 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
489
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
490 default:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
491 goto err;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
492 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
493
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
494 fail = 0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
495
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
496 err:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
497 usb_handle_control_status(fail);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
498 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
499
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
500 void usb_setup_control(void)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
501 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
502 void *buf = ep0_buf[usb.ep_state[0].rx.pingpong];
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
503
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
504 usb.ep_state[0].rx.data01 = USB_DATA01_DATA0;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
505 usb.ep_state[0].tx.data01 = USB_DATA01_DATA1;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
506 usb_rx(&usb.ep_state[0].rx, buf, EP0_BUFSIZE, usb_handle_control, NULL);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
507 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
508
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
509
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
510 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
511 * This is called by the interrupt handler
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
512 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
513 void usb_handle_transaction(struct usb_xfer_info *info)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
514 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
515 enum usb_tok_pid pid = usb_get_xfer_pid(info);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
516 struct usbd_ep_state_t *eps = &usb.ep_state[usb_get_xfer_ep(info)];
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
517 struct usbd_ep_pipe_state_t *s = &eps->pipe[usb_get_xfer_dir(info)];
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
518
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
519 switch (pid) {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
520 case USB_PID_SETUP:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
521 case USB_PID_OUT:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
522 /**
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
523 * If we receive a SETUP transaction, but don't expect
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
524 * it (callback set to somewhere else), stall the EP.
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
525 */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
526 if (pid == USB_PID_SETUP && s->callback != usb_handle_control)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
527 usb_handle_control_status(1);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
528 else
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
529 usb_rx_next(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
530 if (pid == USB_PID_SETUP)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
531 usb_enable_xfers();
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
532 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
533 case USB_PID_IN:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
534 usb_tx_next(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
535 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
536 default:
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
537 break;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
538 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
539 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
540
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
541 struct usbd_ep_pipe_state_t *usb_init_ep(struct usbd_function_ctx_header *ctx, int ep, enum usb_ep_dir dir, size_t size)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
542 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
543 struct usbd_ep_pipe_state_t *s;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
544
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
545 if (dir == USB_EP_RX)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
546 s = &usb.ep_state[ctx->ep_rx_offset + ep].rx;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
547 else
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
548 s = &usb.ep_state[ctx->ep_tx_offset + ep].tx;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
549
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
550 memset(s, 0, sizeof(*s));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
551 s->ep_maxsize = size;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
552 s->ep_num = ep;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
553 s->ep_dir = dir;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
554 usb_pipe_enable(s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
555 return (s);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
556 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
557
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
558 void usb_restart(void)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
559 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
560 const struct usbd_device *identity = usb.identity;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
561 /* XXX reset existing functions? */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
562 memset(&usb, 0, sizeof(usb));
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
563 usb.functions.function = &usb.control_function;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
564 usb.identity = identity;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
565 usb_init_ep(&usb.functions, 0, USB_EP_RX, EP0_BUFSIZE);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
566 usb_init_ep(&usb.functions, 0, USB_EP_TX, EP0_BUFSIZE);
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
567 usb_setup_control();
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
568 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
569
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
570 void usb_attach_function(const struct usbd_function *function, struct usbd_function_ctx_header *ctx)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
571 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
572 /* XXX right now this requires a sequential initialization */
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
573 struct usbd_function_ctx_header *prev = &usb.functions;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
574
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
575 while (prev->next != NULL)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
576 prev = prev->next;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
577 ctx->next = NULL;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
578 ctx->function = function;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
579 ctx->interface_offset = prev->interface_offset + prev->function->interface_count;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
580 ctx->ep_rx_offset = prev->ep_rx_offset + prev->function->ep_rx_count;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
581 ctx->ep_tx_offset = prev->ep_tx_offset + prev->function->ep_tx_count;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
582 prev->next = ctx;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
583 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
584
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
585 void usb_init(const struct usbd_device *identity)
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
586 {
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
587 usb.identity = identity;
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
588 usb_enable();
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
589 }
b091bb09c55f Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff changeset
590