1 /* Copyright (c) 2011,2012 Simon Schubert <2@0x2c.org>.
2 * Modifications by Jacob Alexander 2014 <haata@kiibohd.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // ----- Defines -----
20 #define usb_xfer_info USB_STAT_t
24 // ----- Local Includes -----
27 #include "usb-internal.h"
31 // ----- Functions -----
34 * Kinetis USB driver notes:
35 * We need to manually maintain the DATA0/1 toggling for the SIE.
36 * SETUP transactions always start with a DATA0.
38 * The SIE internally uses pingpong (double) buffering, which is
39 * easily confused with DATA0/DATA1 toggling, and I think even the
40 * Freescale docs confuse the two notions. When BD->DTS is set,
41 * BD->DATA01 will be used to verify/discard incoming DATAx and it
42 * will set the DATAx PID for outgoing tokens. This is not described
43 * as such in the Freescale Kinetis docs, but the Microchip PIC32 OTG
44 * docs are more clear on this; it seems that both Freescale and
45 * Microchip use different versions of the same USB OTG IP core.
47 * http://ww1.microchip.com/downloads/en/DeviceDoc/61126F.pdf
49 * Clear CTL->TOKEN_BUSY after SETUP tokens.
53 static struct USB_BD_t bdt[USB_MAX_EP * 2 *2] __attribute__((section(".usbdescriptortable")));
55 static struct USB_BD_t *
56 usb_get_bd(struct usbd_ep_pipe_state_t *s)
58 return (&bdt[(s->ep_num << 2) | (s->ep_dir << 1) | s->pingpong]);
61 static struct USB_BD_t *
62 usb_get_bd_stat(struct USB_STAT_t *stat)
64 return (((void *)(uintptr_t)bdt + (stat->raw << 1)));
67 void *usb_get_xfer_data(struct usb_xfer_info *i)
69 return (usb_get_bd_stat(i)->addr);
72 enum usb_tok_pid usb_get_xfer_pid(struct usb_xfer_info *i)
74 return (usb_get_bd_stat(i)->tok_pid);
77 int usb_get_xfer_ep(struct usb_xfer_info *i)
82 enum usb_ep_dir usb_get_xfer_dir(struct usb_xfer_info *i)
87 void usb_enable_xfers(void)
89 USB0.ctl.raw = ((struct USB_CTL_t){
95 void usb_set_addr(int addr)
101 void usb_pipe_stall(struct usbd_ep_pipe_state_t *s)
103 volatile struct USB_BD_t *bd = usb_get_bd(s);
104 bd->raw = ((struct USB_BD_BITS_t){
110 void usb_pipe_unstall(struct usbd_ep_pipe_state_t *s)
112 volatile struct USB_BD_t *bd = usb_get_bd(s);
113 struct USB_BD_BITS_t state = { .raw = bd->raw };
115 if (state.own && state.stall)
119 void usb_pipe_enable(struct usbd_ep_pipe_state_t *s)
121 USB0.endpt[s->ep_num].raw |= ((struct USB_ENDPT_t){
122 .eptxen = s->ep_dir == USB_EP_TX,
123 .eprxen = s->ep_dir == USB_EP_RX,
124 .ephshk = 1, /* XXX ISO */
125 .epctldis = s->ep_num != 0
129 void usb_pipe_disable(struct usbd_ep_pipe_state_t *s)
131 USB0.endpt[s->ep_num].raw &= ~((struct USB_ENDPT_t){
132 .eptxen = s->ep_dir == USB_EP_TX,
133 .eprxen = s->ep_dir == USB_EP_RX,
138 size_t usb_ep_get_transfer_size(struct usbd_ep_pipe_state_t *s)
140 struct USB_BD_t *bd = usb_get_bd(s);
144 void usb_queue_next(struct usbd_ep_pipe_state_t *s, void *addr, size_t len)
146 volatile struct USB_BD_t *bd = usb_get_bd(s);
149 /* damn you bitfield problems */
150 bd->raw = ((struct USB_BD_BITS_t){
158 static void usb_reset(void)
160 /* reset pingpong state */
161 /* For some obscure reason, we need to use or here. */
162 USB0.ctl.raw |= ((struct USB_CTL_t){
167 /* clear all interrupt bits - not sure if needed */
168 USB0.istat.raw = 0xff;
169 USB0.errstat.raw = 0xff;
170 USB0.otgistat.raw = 0xff;
172 /* zap also BDT pingpong & queued transactions */
173 memset(bdt, 0, sizeof(bdt));
178 USB0.ctl.raw = ((struct USB_CTL_t){
183 /* we're only interested in reset and transfers */
184 USB0.inten.raw = ((struct USB_ISTAT_t){
191 USB0.usbtrc0.usbresmen = 0;
192 USB0.usbctrl.susp = 0;
195 void usb_enable(void)
197 SIM.sopt2.usbsrc = 1; /* usb from mcg */
198 SIM.scgc4.usbotg = 1; /* enable usb clock */
200 /* reset module - not sure if needed */
201 USB0.usbtrc0.raw = ((struct USB_USBTRC0_t){
205 while (USB0.usbtrc0.usbreset)
208 USB0.bdtpage1 = (uintptr_t)bdt >> 8;
209 USB0.bdtpage2 = (uintptr_t)bdt >> 16;
210 USB0.bdtpage3 = (uintptr_t)bdt >> 24;
212 USB0.control.raw = ((struct USB_CONTROL_t){
213 .dppullupnonotg = 1 /* enable pullup */
216 USB0.usbctrl.raw = 0; /* resume peripheral & disable pulldowns */
217 usb_reset(); /* this will start usb processing */
219 /* really only one thing we want */
220 USB0.inten.raw = ((struct USB_ISTAT_t){
225 * Suspend transceiver now - we'll wake up at reset again.
227 // TODO - Possible removal
228 USB0.usbctrl.susp = 1;
229 USB0.usbtrc0.usbresmen = 1;
232 void USB0_Handler(void)
234 struct USB_ISTAT_t stat = {.raw = USB0.istat.raw };
241 /* XXX need more work for non-0 ep */
242 volatile struct USB_BD_t *bd = usb_get_bd(&usb.ep_state[0].rx);
247 struct usb_xfer_info stat = USB0.stat;
248 usb_handle_transaction(&stat);
251 USB0.inten.sleep = 0;
252 USB0.inten.resume = 1;
253 USB0.usbctrl.susp = 1;
254 USB0.usbtrc0.usbresmen = 1;
257 * Clear interrupts now so that we can detect a fresh
260 USB0.istat.raw = stat.raw;
262 const struct usbd_config *c = usb_get_config_data(-1);
267 * XXX it is unclear whether we will receive a synchronous
268 * resume interrupt if we were in sleep. This code assumes we
271 if (stat.resume || USB0.usbtrc0.usb_resume_int) {
272 USB0.inten.resume = 0;
273 USB0.inten.sleep = 1;
274 USB0.usbtrc0.usbresmen = 0;
275 USB0.usbctrl.susp = 0;
277 const struct usbd_config *c = usb_get_config_data(-1);
281 stat.resume = 1; /* always clear bit */
283 USB0.istat.raw = stat.raw;
291 int usb_tx_serialno(size_t reqlen)
293 struct usb_desc_string_t *d;
294 const size_t nregs = 3;
296 * actually 4, but UIDH is 0xffffffff. Also our output buffer
297 * is only 64 bytes, and 128 bit + desc header exceeds this by
300 const size_t len = nregs * 4 * 2 * 2 + sizeof(*d);
302 d = usb_ep0_tx_inplace_prepare(len);
308 d->bDescriptorType = USB_DESC_STRING;
311 for (size_t reg = 0; reg < nregs; ++reg) {
312 /* registers run MSW first */
313 uint32_t val = (&SIM.uidmh)[reg];
315 for (size_t bits = 32; bits > 0; bits -= 4, val <<= 4) {
316 int nibble = val >> 28;
319 nibble += 'a' - '9' - 1;
320 ((char16_t *)d->bString)[bufpos++] = nibble + '0';
323 usb_ep0_tx(d, len, reqlen, NULL, NULL);