usb.c (8931B)
1 /* usb.c 2 * 3 * Copyright 2011 Brian Swetland <swetland@frotz.net> 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <fw/types.h> 19 #include <fw/lib.h> 20 #include <fw/io.h> 21 22 #include <arch/hardware.h> 23 #include <protocol/usb.h> 24 25 void usb_handle_irq(void); 26 27 void irq_usb_lp(void) { 28 printx("IRQ USB LP\n"); 29 for (;;) ; 30 } 31 void irq_usb_hp(void) { 32 printx("IRQ USB HP\n"); 33 for (;;) ; 34 } 35 36 static volatile int _usb_online = 0; 37 static void *ep1_rx_data; 38 static volatile int ep1_rx_status; 39 static volatile int ep1_tx_busy; 40 41 static unsigned ep0rxb = USB_SRAM_BASE + 0x0040; /* 64 bytes */ 42 static unsigned ep0txb = USB_SRAM_BASE + 0x00c0; /* 64 bytes */ 43 static unsigned ep1rxb = USB_SRAM_BASE + 0x0140; /* 64 bytes */ 44 static unsigned ep1txb = USB_SRAM_BASE + 0x01c0; /* 64 bytes */ 45 46 #define ADDR2USB(n) (((n) & 0x3FF) >> 1) 47 48 void usb_handle_reset(void) { 49 _usb_online = 0; 50 ep1_tx_busy = 0; 51 ep1_rx_status = -ENODEV; 52 53 writel(0, USB_BTABLE); 54 writel(ADDR2USB(ep0txb), USB_ADDR_TX(0)); 55 writel(ADDR2USB(ep0rxb), USB_ADDR_RX(0)); 56 writel(0, USB_COUNT_TX(0)); 57 writel(USB_RX_SZ_64, USB_COUNT_RX(0)); 58 59 writel(ADDR2USB(ep1txb), USB_ADDR_TX(1)); 60 writel(ADDR2USB(ep1rxb), USB_ADDR_RX(1)); 61 writel(0, USB_COUNT_TX(1)); 62 writel(USB_RX_SZ_64, USB_COUNT_RX(1)); 63 64 writel(0x0 | USB_EPR_TYPE_CONTROL | 65 USB_EPR_RX_NAK | USB_EPR_TX_NAK, 66 USB_EPR(0)); 67 68 writel(0x1 | USB_EPR_TYPE_BULK | 69 USB_EPR_RX_NAK | USB_EPR_TX_NAK, 70 USB_EPR(1)); 71 72 writel(0x00 | USB_DADDR_ENABLE, USB_DADDR); 73 } 74 75 static u8 _dev00[] = { 76 18, /* size */ 77 DSC_DEVICE, 78 0x00, 0x01, /* version */ 79 0xFF, /* class */ 80 0x00, /* subclass */ 81 0x00, /* protocol */ 82 0x40, /* maxpacket0 */ 83 0xd1, 0x18, /* VID */ 84 0x02, 0x65, /* PID */ 85 0x00, 0x01, /* version */ 86 0x00, /* manufacturer string */ 87 0x00, /* product string */ 88 0x00, /* serialno string */ 89 0x01, /* configurations */ 90 }; 91 92 static u8 _cfg00[] = { 93 9, 94 DSC_CONFIG, 95 0x20, 0x00, /* total length */ 96 0x01, /* ifc count */ 97 0x01, /* configuration value */ 98 0x00, /* configuration string */ 99 0x80, /* attributes */ 100 50, /* mA/2 */ 101 102 9, 103 DSC_INTERFACE, 104 0x00, /* interface number */ 105 0x00, /* alt setting */ 106 0x02, /* ept count */ 107 0xFF, /* class */ 108 0x00, /* subclass */ 109 0x00, /* protocol */ 110 0x00, /* interface string */ 111 112 7, 113 DSC_ENDPOINT, 114 0x81, /* address */ 115 0x02, /* bulk */ 116 0x40, 0x00, /* max packet size */ 117 0x00, /* interval */ 118 119 7, 120 DSC_ENDPOINT, 121 0x01, /* address */ 122 0x02, /* bulk */ 123 0x40, 0x00, /* max packet size */ 124 0x00, /* interval */ 125 126 }; 127 128 static struct { 129 u16 id; 130 u16 len; 131 u8 *desc; 132 } dtable[] = { 133 { 0x0100, sizeof(_dev00), _dev00 }, 134 { 0x0200, sizeof(_cfg00), _cfg00 }, 135 }; 136 137 unsigned load_desc(unsigned id) { 138 unsigned n, len; 139 for (n = 0; n < (sizeof(dtable)/sizeof(dtable[0])); n++) { 140 if (id == dtable[n].id) { 141 u16 *src = (u16*) dtable[n].desc; 142 u32 *dst = (void*) ep0txb; 143 len = dtable[n].len; 144 n = (len & 1) + (len >> 1); 145 while (n--) 146 *dst++ = *src++; 147 return len; 148 } 149 } 150 printx("? %h\n", id); 151 return 0; 152 } 153 154 155 /* exclude T and W0C bits */ 156 #define EPMASK (USB_EPR_TYPE_MASK | USB_EPR_DBL_BUF | USB_EPR_ADDR_MASK) 157 158 #define EP0_TX_ACK_ADDR 0 /* sending ACK, then changing address */ 159 #define EP0_TX_ACK 1 /* sending ACK */ 160 #define EP0_RX_ACK 2 /* receiving ACK */ 161 #define EP0_TX 3 /* sending data */ 162 #define EP0_RX 4 /* receiving data */ 163 #define EP0_IDLE 5 /* waiting for SETUP */ 164 165 static void ep0_recv_ack(unsigned n) { 166 writel((n & EPMASK) | USB_EPR_RX_STALL | USB_EPR_STATUS_OUT, USB_EPR(0)); 167 } 168 static void ep0_send_ack(unsigned n) { 169 writel(0, USB_COUNT_TX(0)); 170 writel((n & EPMASK) | USB_EPR_TX_STALL, USB_EPR(0)); 171 } 172 173 static u8 ep0state = EP0_IDLE; 174 static u8 newaddr; 175 176 void usb_handle_ep0_tx(unsigned n) { 177 switch (ep0state) { 178 case EP0_TX_ACK_ADDR: 179 writel(newaddr | USB_DADDR_ENABLE, USB_DADDR); 180 case EP0_TX_ACK: 181 ep0state = EP0_IDLE; 182 writel((n & EPMASK), USB_EPR(0)); 183 break; 184 case EP0_TX: 185 ep0state = EP0_RX_ACK; 186 ep0_recv_ack(n); 187 break; 188 } 189 } 190 191 void usb_handle_ep0_rx(unsigned n) { 192 switch (ep0state) { 193 case EP0_RX_ACK: 194 /* ack txn and make sure STATUS_OUT is cleared */ 195 writel(((n & EPMASK) & (~USB_EPR_STATUS_OUT)) | 196 USB_EPR_CTR_TX, USB_EPR(0)); 197 ep0state = EP0_IDLE; 198 break; 199 case EP0_RX: 200 ; 201 } 202 } 203 204 void usb_handle_ep0_setup(unsigned n) { 205 u16 req, val, idx, len, x; 206 207 req = readl(ep0rxb + 0x00); 208 val = readl(ep0rxb + 0x04); 209 idx = readl(ep0rxb + 0x08); 210 len = readl(ep0rxb + 0x0C); 211 x = readl(USB_COUNT_RX(0)); 212 213 /* release SETUP latch by acking RX */ 214 writel((n & EPMASK), USB_EPR(0)); 215 216 switch (req) { 217 case GET_DESCRIPTOR: 218 x = load_desc(val); 219 if (x == 0) 220 goto error; 221 if (x > len) 222 x = len; 223 ep0state = EP0_TX; 224 writel(x, USB_COUNT_TX(0)); 225 writel((n & EPMASK) | USB_EPR_TX_STALL, USB_EPR(0)); 226 return; 227 case SET_ADDRESS: 228 ep0state = EP0_TX_ACK_ADDR; 229 newaddr = val & 0x7F; 230 ep0_send_ack(n); 231 return; 232 case SET_CONFIGURATION: 233 ep0state = EP0_TX_ACK; 234 ep0_send_ack(n); 235 _usb_online = 1; /* TODO: check value */ 236 return; 237 } 238 239 /* unknown request */ 240 printx("? %b %b %h %h %h\n", req, req >> 8, val, idx, len); 241 242 error: 243 /* error, stall TX */ 244 writel((n & EPMASK) | USB_EPR_TX_NAK | USB_EPR_TX_STALL, USB_EPR(0)); 245 } 246 247 void usb_handle_ep0(void) { 248 unsigned n = readl(USB_EPR(0)); 249 if (n & USB_EPR_SETUP) { 250 usb_handle_ep0_setup(n); 251 } else if (n & USB_EPR_CTR_TX) { 252 usb_handle_ep0_tx(n); 253 } else if (n & USB_EPR_CTR_RX) { 254 usb_handle_ep0_rx(n); 255 } 256 } 257 258 void usb_handle_ep1(void) { 259 unsigned n; 260 int len; 261 262 n = readl(USB_EPR(1)); 263 if (n & USB_EPR_CTR_RX) { 264 /* first, clear RX CTR */ 265 writel((n & EPMASK) | USB_EPR_CTR_TX, USB_EPR(1)); 266 267 u32 *src = (void*) ep1rxb; 268 u16 *dst = (void*) ep1_rx_data; 269 len = readl(USB_COUNT_RX(1)) & 0x3FF; 270 ep1_rx_status = len; 271 while (len > 0) { 272 *dst++ = *src++; 273 len -= 2; 274 } 275 } 276 if (n & USB_EPR_CTR_TX) { 277 /* first, clear TX CTR */ 278 writel((n & EPMASK) | USB_EPR_CTR_RX, USB_EPR(1)); 279 ep1_tx_busy = 0; 280 } 281 } 282 283 int usb_recv(void *_data, int count) { 284 int r, rx = 0; 285 unsigned n; 286 u8 *data = _data; 287 288 while (!_usb_online) 289 usb_handle_irq(); 290 291 while (count > 0) { 292 if (!_usb_online) 293 return -ENODEV; 294 295 ep1_rx_data = data; 296 ep1_rx_status = -EBUSY; 297 298 /* move from NAK to VALID, don't touch any other bits */ 299 n = readl(USB_EPR(1)) & EPMASK; 300 writel(n | USB_EPR_CTR_RX | USB_EPR_CTR_TX | USB_EPR_RX_STALL, USB_EPR(1)); 301 302 while (ep1_rx_status == -EBUSY) 303 usb_handle_irq(); 304 305 r = ep1_rx_status; 306 307 if (r < 0) 308 return r; 309 if (r > count) 310 r = count; 311 data += r; 312 rx += r; 313 count -= r; 314 315 /* terminate on short packet */ 316 if (r != 64) 317 break; 318 } 319 320 return rx; 321 } 322 323 int usb_xmit(void *data, int len) { 324 int tx = 0; 325 int n; 326 u16 *src = data; 327 328 while (len > 0) { 329 u32 *dst = (void*) ep1txb; 330 int xfer = (len > 64) ? 64 : len; 331 332 if (!_usb_online) 333 return -ENODEV; 334 335 while (ep1_tx_busy) 336 usb_handle_irq(); 337 338 writel(xfer, USB_COUNT_TX(1)); 339 //printx("%x <- %x (%x)\n",dst, src, xfer); 340 len -= xfer; 341 tx += xfer; 342 343 while (xfer > 0) { 344 *dst++ = *src++; 345 xfer -= 2; 346 } 347 348 /* move from NAK to VALID, don't touch any other bits */ 349 n = readl(USB_EPR(1)) & EPMASK; 350 writel(n | USB_EPR_CTR_RX | USB_EPR_CTR_TX | USB_EPR_TX_STALL, USB_EPR(1)); 351 352 ep1_tx_busy = 1; 353 354 } 355 356 return tx; 357 } 358 359 void usb_init(unsigned vid, unsigned pid, const char *mfg_string, const char *prod_string) { 360 unsigned n; 361 362 _dev00[8] = vid; 363 _dev00[9] = vid >> 8; 364 _dev00[10] = pid; 365 _dev00[11] = pid >> 8; 366 367 /* enable GPIOC */ 368 writel(readl(RCC_APB2ENR) | RCC_APB2_GPIOC, RCC_APB2ENR); 369 370 /* configure GPIOC-12 */ 371 writel(1 << 12, GPIOC_BASE + GPIO_BSR); 372 n = readl(GPIOC_BASE + GPIO_CRH); 373 n = (n & 0xFFF0FFFF) | 0x00050000; 374 writel(n, GPIOC_BASE + GPIO_CRH); 375 376 printx("usb_init()\n"); 377 378 /* enable USB clock */ 379 writel(readl(RCC_APB1ENR) | RCC_APB1_USB, RCC_APB1ENR); 380 381 /* reset */ 382 writel(USB_CR_PDWN | USB_CR_FRES, USB_CR); 383 for (n = 0; n < 100000; n++) asm("nop"); 384 writel(~USB_CR_PDWN, USB_CR); /* power up analog block */ 385 for (n = 0; n < 100000; n++) asm("nop"); 386 writel(0, USB_CR); 387 writel(0, USB_ISR); 388 389 usb_handle_reset(); 390 391 /* become active on the bus */ 392 writel(1 << 12, GPIOC_BASE + GPIO_BRR); 393 } 394 395 void usb_handle_irq(void) { 396 unsigned n; 397 for (;;) { 398 n = readl(USB_ISR); 399 if (n & USB_RESETM) { 400 usb_handle_reset(); 401 writel(~USB_RESETM, USB_ISR); 402 continue; 403 } 404 if (n & USB_CTRM) { 405 if ((n & 0x0F) == 0) 406 usb_handle_ep0(); 407 if ((n & 0x0F) == 1) 408 usb_handle_ep1(); 409 writel(~USB_CTRM, USB_ISR); 410 continue; 411 } 412 break; 413 } 414 } 415