Mercurial > louis > kiibohd-controller
annotate Bootloader/kinetis.c @ 412:e7a3be42ae1e
Debug code for interconnect cable debugging
author | Jacob Alexander <haata@kiibohd.com> |
---|---|
date | Sat, 20 Feb 2016 13:27:49 -0800 |
parents | ab4515606277 |
children |
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 // ----- Defines ----- |
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 #define usb_xfer_info USB_STAT_t |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
21 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
22 |
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 // ----- Local Includes ----- |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
25 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
26 #include "mchck.h" |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
27 #include "usb-internal.h" |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
28 |
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 // ----- Functions ----- |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
32 |
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 * Kinetis USB driver notes: |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
35 * We need to manually maintain the DATA0/1 toggling for the SIE. |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
36 * SETUP transactions always start with a DATA0. |
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 * The SIE internally uses pingpong (double) buffering, which is |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
39 * easily confused with DATA0/DATA1 toggling, and I think even the |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
40 * Freescale docs confuse the two notions. When BD->DTS is set, |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
41 * BD->DATA01 will be used to verify/discard incoming DATAx and it |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
42 * will set the DATAx PID for outgoing tokens. This is not described |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
43 * as such in the Freescale Kinetis docs, but the Microchip PIC32 OTG |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
44 * docs are more clear on this; it seems that both Freescale and |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
45 * Microchip use different versions of the same USB OTG IP core. |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
46 * |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
47 * http://ww1.microchip.com/downloads/en/DeviceDoc/61126F.pdf |
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 * Clear CTL->TOKEN_BUSY after SETUP tokens. |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
50 */ |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
51 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
52 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
53 static struct USB_BD_t bdt[USB_MAX_EP * 2 *2] __attribute__((section(".usbdescriptortable"))); |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
54 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
55 static struct USB_BD_t * |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
56 usb_get_bd(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
57 { |
308 | 58 return (&bdt[(s->ep_num << 2) | (s->ep_dir << 1) | s->pingpong]); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
59 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
60 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
61 static struct USB_BD_t * |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
62 usb_get_bd_stat(struct USB_STAT_t *stat) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
63 { |
308 | 64 return (((void *)(uintptr_t)bdt + (stat->raw << 1))); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
65 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
66 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
67 void *usb_get_xfer_data(struct usb_xfer_info *i) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
68 { |
308 | 69 return (usb_get_bd_stat(i)->addr); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
70 } |
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 enum usb_tok_pid usb_get_xfer_pid(struct usb_xfer_info *i) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
73 { |
308 | 74 return (usb_get_bd_stat(i)->tok_pid); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
75 } |
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 int usb_get_xfer_ep(struct usb_xfer_info *i) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
78 { |
308 | 79 return (i->ep); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
80 } |
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 enum usb_ep_dir usb_get_xfer_dir(struct usb_xfer_info *i) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
83 { |
308 | 84 return (i->dir); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
85 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
86 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
87 void usb_enable_xfers(void) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
88 { |
308 | 89 USB0.ctl.raw = ((struct USB_CTL_t){ |
90 .txd_suspend = 0, | |
91 .usben = 1 | |
92 }).raw; | |
193
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 void usb_set_addr(int addr) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
96 { |
308 | 97 USB0.addr.raw = addr; |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
98 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
99 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
100 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
101 void usb_pipe_stall(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
102 { |
308 | 103 volatile struct USB_BD_t *bd = usb_get_bd(s); |
104 bd->raw = ((struct USB_BD_BITS_t){ | |
105 .stall = 1, | |
106 .own = 1 | |
107 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
108 } |
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 void usb_pipe_unstall(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
111 { |
308 | 112 volatile struct USB_BD_t *bd = usb_get_bd(s); |
113 struct USB_BD_BITS_t state = { .raw = bd->raw }; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
114 |
308 | 115 if (state.own && state.stall) |
116 bd->raw = 0; | |
193
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 void usb_pipe_enable(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
120 { |
308 | 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 | |
126 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
127 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
128 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
129 void usb_pipe_disable(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
130 { |
308 | 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, | |
134 .epctldis = 1 | |
135 }).raw; | |
193
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 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
138 size_t usb_ep_get_transfer_size(struct usbd_ep_pipe_state_t *s) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
139 { |
308 | 140 struct USB_BD_t *bd = usb_get_bd(s); |
141 return (bd->bc); | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
142 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
143 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
144 void usb_queue_next(struct usbd_ep_pipe_state_t *s, void *addr, size_t len) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
145 { |
308 | 146 volatile struct USB_BD_t *bd = usb_get_bd(s); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
147 |
308 | 148 bd->addr = addr; |
149 /* damn you bitfield problems */ | |
150 bd->raw = ((struct USB_BD_BITS_t){ | |
151 .dts = 1, | |
152 .own = 1, | |
153 .data01 = s->data01, | |
154 .bc = len, | |
155 }).raw; | |
193
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 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
158 static void usb_reset(void) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
159 { |
308 | 160 /* reset pingpong state */ |
161 /* For some obscure reason, we need to use or here. */ | |
162 USB0.ctl.raw |= ((struct USB_CTL_t){ | |
163 .txd_suspend = 1, | |
164 .oddrst = 1, | |
165 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
166 |
308 | 167 /* clear all interrupt bits - not sure if needed */ |
168 USB0.istat.raw = 0xff; | |
169 USB0.errstat.raw = 0xff; | |
170 USB0.otgistat.raw = 0xff; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
171 |
308 | 172 /* zap also BDT pingpong & queued transactions */ |
173 memset(bdt, 0, sizeof(bdt)); | |
174 USB0.addr.raw = 0; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
175 |
308 | 176 usb_restart(); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
177 |
308 | 178 USB0.ctl.raw = ((struct USB_CTL_t){ |
179 .txd_suspend = 0, | |
180 .usben = 1 | |
181 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
182 |
308 | 183 /* we're only interested in reset and transfers */ |
184 USB0.inten.raw = ((struct USB_ISTAT_t){ | |
185 .tokdne = 1, | |
186 .usbrst = 1, | |
187 .stall = 1, | |
188 .sleep = 1, | |
189 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
190 |
308 | 191 USB0.usbtrc0.usbresmen = 0; |
192 USB0.usbctrl.susp = 0; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
193 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
194 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
195 void usb_enable(void) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
196 { |
308 | 197 SIM.sopt2.usbsrc = 1; /* usb from mcg */ |
198 SIM.scgc4.usbotg = 1; /* enable usb clock */ | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
199 |
308 | 200 /* reset module - not sure if needed */ |
201 USB0.usbtrc0.raw = ((struct USB_USBTRC0_t){ | |
202 .usbreset = 1, | |
203 .usbresmen = 1 | |
204 }).raw; | |
205 while (USB0.usbtrc0.usbreset) | |
206 /* NOTHING */; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
207 |
308 | 208 USB0.bdtpage1 = (uintptr_t)bdt >> 8; |
209 USB0.bdtpage2 = (uintptr_t)bdt >> 16; | |
210 USB0.bdtpage3 = (uintptr_t)bdt >> 24; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
211 |
308 | 212 USB0.control.raw = ((struct USB_CONTROL_t){ |
213 .dppullupnonotg = 1 /* enable pullup */ | |
214 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
215 |
308 | 216 USB0.usbctrl.raw = 0; /* resume peripheral & disable pulldowns */ |
217 usb_reset(); /* this will start usb processing */ | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
218 |
308 | 219 /* really only one thing we want */ |
220 USB0.inten.raw = ((struct USB_ISTAT_t){ | |
221 .usbrst = 1, | |
222 }).raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
223 |
308 | 224 /** |
225 * Suspend transceiver now - we'll wake up at reset again. | |
226 */ | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
227 // TODO - Possible removal |
308 | 228 USB0.usbctrl.susp = 1; |
229 USB0.usbtrc0.usbresmen = 1; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
230 } |
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 void USB0_Handler(void) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
233 { |
308 | 234 struct USB_ISTAT_t stat = {.raw = USB0.istat.raw }; |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
235 |
308 | 236 if (stat.usbrst) { |
237 usb_reset(); | |
238 return; | |
239 } | |
240 if (stat.stall) { | |
241 /* XXX need more work for non-0 ep */ | |
242 volatile struct USB_BD_t *bd = usb_get_bd(&usb.ep_state[0].rx); | |
243 if (bd->stall) | |
244 usb_setup_control(); | |
245 } | |
246 if (stat.tokdne) { | |
247 struct usb_xfer_info stat = USB0.stat; | |
248 usb_handle_transaction(&stat); | |
249 } | |
250 if (stat.sleep) { | |
251 USB0.inten.sleep = 0; | |
252 USB0.inten.resume = 1; | |
253 USB0.usbctrl.susp = 1; | |
254 USB0.usbtrc0.usbresmen = 1; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
255 |
308 | 256 /** |
257 * Clear interrupts now so that we can detect a fresh | |
258 * resume later on. | |
259 */ | |
260 USB0.istat.raw = stat.raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
261 |
308 | 262 const struct usbd_config *c = usb_get_config_data(-1); |
263 if (c && c->suspend) | |
264 c->suspend(); | |
265 } | |
266 /** | |
267 * XXX it is unclear whether we will receive a synchronous | |
268 * resume interrupt if we were in sleep. This code assumes we | |
269 * do. | |
270 */ | |
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; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
276 |
308 | 277 const struct usbd_config *c = usb_get_config_data(-1); |
278 if (c && c->resume) | |
279 c->resume(); | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
280 |
308 | 281 stat.resume = 1; /* always clear bit */ |
282 } | |
283 USB0.istat.raw = stat.raw; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
284 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
285 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
286 void usb_poll(void) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
287 { |
308 | 288 USB0_Handler(); |
193
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 |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
291 int usb_tx_serialno(size_t reqlen) |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
292 { |
308 | 293 struct usb_desc_string_t *d; |
294 const size_t nregs = 3; | |
295 /** | |
296 * actually 4, but UIDH is 0xffffffff. Also our output buffer | |
297 * is only 64 bytes, and 128 bit + desc header exceeds this by | |
298 * 2 bytes. | |
299 */ | |
300 const size_t len = nregs * 4 * 2 * 2 + sizeof(*d); | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
301 |
308 | 302 d = usb_ep0_tx_inplace_prepare(len); |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
303 |
308 | 304 if (d == NULL) |
305 return (-1); | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
306 |
308 | 307 d->bLength = len; |
308 d->bDescriptorType = USB_DESC_STRING; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
309 |
308 | 310 size_t bufpos = 0; |
311 for (size_t reg = 0; reg < nregs; ++reg) { | |
312 /* registers run MSW first */ | |
313 uint32_t val = (&SIM.uidmh)[reg]; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
314 |
308 | 315 for (size_t bits = 32; bits > 0; bits -= 4, val <<= 4) { |
316 int nibble = val >> 28; | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
317 |
308 | 318 if (nibble > 9) |
319 nibble += 'a' - '9' - 1; | |
320 ((char16_t *)d->bString)[bufpos++] = nibble + '0'; | |
321 } | |
322 } | |
323 usb_ep0_tx(d, len, reqlen, NULL, NULL); | |
324 return (0); | |
193
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
325 } |
b091bb09c55f
Adding McHCK DFU Bootloader
Jacob Alexander <haata@kiibohd.com>
parents:
diff
changeset
|
326 |