Changeset 224 for rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBCore.cpp
- Timestamp:
- Apr 30, 2016, 11:29:25 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBCore.cpp
r136 r224 1 // Copyright (c) 2010, Peter Barrett2 1 /* 3 ** Permission to use, copy, modify, and/or distribute this software for 4 ** any purpose with or without fee is hereby granted, provided that the 5 ** above copyright notice and this permission notice appear in all copies. 6 ** 7 ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 8 ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 9 ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 10 ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 11 ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 12 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 13 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 14 ** SOFTWARE. 2 Copyright (c) 2015 Arduino LLC. All right reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library 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. 12 See the GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15 17 */ 18 /* 19 **Modified 04/04/2016 by Arduino.org development team 20 */ 21 22 #include <Arduino.h> 23 24 #include "SAMD21_USBDevice.h" 25 #include "USB_host.h" 16 26 17 27 #include <stdlib.h> 18 28 #include <stdio.h> 19 29 #include <stdint.h> 20 //#include "../Arduino.h" 21 22 #include "sam.h" 23 #include "wiring_constants.h" 24 #include "USBCore.h" 25 #include "USB/USB_device.h" // needed for USB PID define 26 #include "USBDesc.h" 27 #include "USBAPI.h" 28 29 #define TRACE_CORE(x) 30 31 //================================================================== 32 33 34 35 /* 36 #if (defined CDC_ENABLED) && defined(HID_ENABLED) 37 //#define USB_PID_ZERO 0x004B // CDC and HID 38 #define USB_PID_ZERO 0x804d // CDC only 39 #else 40 #if (defined CDC_ENABLED) 41 #define USB_PID_ZERO 0x804d // CDC only usbserial.name 42 #else 43 #define USB_PID_ZERO 0x804d // HID only 44 #endif 45 #endif 46 */ 47 48 #define USB_PID_ZERO_PRO 0x804d 49 50 // USB Device 51 //#define USB_VID 0x2a03 // arduino srl vid 52 //#undef USB_PID 53 //#define USB_PID USB_PID_ZERO 54 55 //================================================================== 30 #include <limits.h> 31 32 USBDevice_SAMD21G18x usbd; 56 33 57 34 static char isRemoteWakeUpEnabled = 0; 58 35 static char isEndpointHalt = 0; 36 37 extern void (*gpf_isr)(void); 59 38 60 39 … … 64 43 }; 65 44 45 #define USB_PID_ZERO_PRO 0x804d 46 #define USB_PRODUCT "Arduino M0 Pro" 66 47 #ifndef USB_PRODUCT 67 48 // Use a hardcoded product name if none is provided … … 88 69 89 70 90 91 // DEVICE DESCRIPTOR92 71 #if (defined CDC_ENABLED) && defined(HID_ENABLED) 93 72 const DeviceDescriptor USB_DeviceDescriptor = … … 101 80 #endif 102 81 82 103 83 //================================================================== 104 84 105 85 volatile uint32_t _usbConfiguration = 0; 106 volatile uint32_t _usbInitialized = 0;107 86 volatile uint32_t _usbSetInterface = 0; 108 87 88 static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0"))) 89 uint8_t udd_ep_out_cache_buffer[7][64]; 90 91 static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0"))) 92 uint8_t udd_ep_in_cache_buffer[7][64]; 93 109 94 //================================================================== 110 95 111 112 // Number of bytes, assumes a rx endpoint 113 uint32_t USBD_Available(uint32_t ep) 114 { 115 return UDD_FifoByteCount(ep); 116 } 117 118 // Non Blocking receive 119 // Return number of bytes read 120 uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len) 121 { 122 if (!_usbConfiguration || len < 0) 96 bool _dry_run = false; 97 bool _pack_message = false; 98 uint16_t _pack_size = 0; 99 uint8_t _pack_buffer[256]; 100 101 102 void packMessages(bool val) 103 { 104 if (val) { 105 _pack_message = true; 106 _pack_size = 0; 107 } else { 108 _pack_message = false; 109 USBD_SendControl(_pack_buffer, _pack_size); 110 } 111 } 112 113 // Blocking Send of data to an endpoint 114 uint32_t USBD_Send(uint32_t ep, const void *data, uint32_t len) 115 { 116 uint32_t length = 0; 117 118 if (!_usbConfiguration) 123 119 return -1; 124 125 uint32_t n = UDD_FifoByteCount(ep); 126 len = min(n,len); 127 n = len; 128 uint8_t* dst = (uint8_t*)d; 129 while (n--) 130 *dst++ = UDD_Recv8(ep); 131 132 133 134 135 if (len && !UDD_FifoByteCount(ep)) // release empty buffer 136 UDD_ReleaseRX(ep); 137 138 //----- Tx & Rx led blinking during transmission ----- begin ---- 139 PORT->Group[1].OUTTGL.reg =0x00000008 ; //RxLED 140 for(int i=0; i < 100000; i++) 141 { 142 asm("NOP"); 143 } 144 PORT->Group[1].OUTTGL.reg =0x00000008 ; 145 //----- Tx & Rx led blinking during transmission ----- end ---- 120 if (len > 16384) 121 return -1; 122 123 PORT->Group[0].OUTCLR.reg =0x08000000 ; //TxLED on 124 // Flash area 125 while (len != 0) 126 { 127 if (len >= 64) { 128 length = 64; 129 } else { 130 length = len; 131 } 132 133 /* memcopy could be safer in multi threaded environment */ 134 memcpy(&udd_ep_in_cache_buffer[ep], data, length); 135 136 usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); 137 138 usbd.epBank1SetByteCount(ep, length); 139 140 // Clear the transfer complete flag 141 usbd.epBank1AckTransferComplete(ep); 142 143 // RAM buffer is full, we can send data (IN) 144 usbd.epBank1SetReady(ep); 145 146 // Wait for transfer to complete 147 while (!usbd.epBank1IsTransferComplete(ep)) { 148 ; // need fire exit. 149 } 150 len -= length; 151 data = (char *)data + length; 152 } 146 153 return len; 147 154 } 148 155 149 // Recv 1 byte if ready 150 uint32_t USBD_Recv(uint32_t ep) 151 { 152 uint8_t c; 153 if (USBD_Recv(ep, &c, 1) != 1) 154 return -1; 155 else 156 return c; 157 } 158 159 // Blocking Send of data to an endpoint 160 uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len) 161 { 162 int r = len; 163 const uint8_t* data = (const uint8_t*)d; 164 165 if (!_usbConfiguration) 166 { 167 TRACE_CORE(printf("pb conf\n\r");) 168 return -1; 169 } 170 UDD_Send(ep, data, len); 171 172 /* Clear the transfer complete flag */ 173 udd_clear_transf_cplt(ep); 174 /* Set the bank as ready */ 175 udd_bk_rdy(ep); 176 177 /* Wait for transfer to complete */ 178 while (! udd_is_transf_cplt(ep)); // need fire exit. 179 180 //----- Tx & Rx led blinking during transmission ----- begin ---- 181 PORT->Group[0].OUTTGL.reg =0x08000000 ; //TxLED 182 for(int i=0; i < 100000; i++) 183 { 184 asm("NOP"); 185 } 186 PORT->Group[0].OUTTGL.reg =0x08000000 ; 187 /*for(int i=0; i < 100000; i++) 188 { 189 asm("NOP"); 190 }*/ 191 //----- Tx & Rx led blinking during transmission ----- end ---- 192 return r; 193 } 194 195 uint32_t USBD_SendControl(uint8_t flags, const void* d, uint32_t len) 196 { 197 const uint8_t* data = (const uint8_t*)d; 156 uint32_t USBD_armSend(uint32_t ep, const void* data, uint32_t len) 157 { 158 memcpy(&udd_ep_in_cache_buffer[ep], data, len); 159 160 // Get endpoint configuration from setting register 161 usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); 162 usbd.epBank1SetMultiPacketSize(ep, 0); 163 usbd.epBank1SetByteCount(ep, len); 164 165 return len; 166 } 167 168 uint32_t USBD_SendControl(const void* _data, uint32_t len) 169 { 170 const uint8_t *data = reinterpret_cast<const uint8_t *>(_data); 198 171 uint32_t length = len; 199 172 uint32_t sent = 0; 200 173 uint32_t pos = 0; 201 174 202 TRACE_CORE(printf("=> USBD_SendControl TOTAL len=%lu\r\n", len);) 203 204 while (len > 0) 205 { 206 sent = UDD_Send(EP0, data + pos, len); 207 TRACE_CORE(printf("=> USBD_SendControl sent=%lu\r\n", sent);) 208 pos += sent; 209 len -= sent; 210 } 175 if (_dry_run == true) 176 return length; 177 178 if (_pack_message == true) { 179 memcpy(&_pack_buffer[_pack_size], data, len); 180 _pack_size += len; 181 return length; 182 } 183 184 while (len > 0) 185 { 186 sent = USBD_armSend(EP0, data + pos, len); 187 pos += sent; 188 len -= sent; 189 } 211 190 212 191 return length; 213 192 } 214 193 215 // Send a USB descriptor string. The string is stored as a 216 // plain ASCII string but is sent out as UTF-16 with the 217 // correct 2-byte prefix 218 static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) 219 { 220 uint16_t buff[ 64];194 bool USBD_SendStringDescriptor(const uint8_t *string, uint8_t maxlen) 195 { 196 if (maxlen < 2) 197 return false; 198 199 uint16_t buff[maxlen/2]; 221 200 int l = 1; 222 201 223 wLength-= 2;224 while (*string && wLength>0)202 maxlen -= 2; 203 while (*string && maxlen>0) 225 204 { 226 205 buff[l++] = (uint8_t)(*string++); 227 wLength-= 2;206 maxlen -= 2; 228 207 } 229 208 buff[0] = (3<<8) | (l*2); 230 209 231 return USBD_SendControl(0, (uint8_t*)buff, l*2); 232 } 233 234 uint32_t USBD_RecvControl(void* d, uint32_t len) 235 { 236 udd_ack_out_received(0); 237 238 return len; 239 } 240 241 // Handle CLASS_INTERFACE requests 242 bool USBD_ClassInterfaceRequest(Setup& setup) 243 { 244 uint8_t i = setup.wIndex; 245 246 TRACE_CORE(printf("=> USBD_ClassInterfaceRequest\r\n");) 247 248 #ifdef CDC_ENABLED 249 if (CDC_ACM_INTERFACE == i) 250 { 251 if( CDC_Setup(setup) == false ) 252 { 253 send_zlp(); 254 } 210 return USBD_SendControl((uint8_t*)buff, l*2); 211 } 212 213 uint8_t USBD_SendInterfaces(uint32_t* total) 214 { 215 uint8_t interfaces = 0; 216 217 #if defined(CDC_ENABLED) 218 total[0] += CDC_GetInterface(&interfaces); 219 #endif 220 221 return interfaces; 222 } 223 224 // Construct a dynamic configuration descriptor 225 // This really needs dynamic endpoint allocation etc 226 uint32_t USBD_SendConfiguration(uint32_t maxlen) 227 { 228 uint32_t total = 0; 229 // Count and measure interfaces 230 _dry_run = true; 231 uint8_t interfaces = USBD_SendInterfaces(&total); 232 233 _Pragma("pack(1)") 234 ConfigDescriptor config = D_CONFIG((uint16_t)(total + sizeof(ConfigDescriptor)), interfaces); 235 _Pragma("pack()") 236 237 // Now send them 238 _dry_run = false; 239 240 if (maxlen == sizeof(ConfigDescriptor)) { 241 USBD_SendControl(&config, sizeof(ConfigDescriptor)); 255 242 return true; 256 243 } 257 #endif 258 259 #ifdef HID_ENABLED 260 if (HID_INTERFACE == i) 261 { 262 if( HID_Setup(setup) == true ) 263 { 264 send_zlp(); 265 } 266 return true; 267 } 268 #endif 269 270 return false; 271 } 272 273 // Construct a dynamic configuration descriptor 274 // This really needs dynamic endpoint allocation etc 275 // TODO 276 static bool USBD_SendConfiguration(uint32_t maxlen) 277 { 278 uint8_t cache_buffer[128]; 279 uint8_t i; 280 281 const uint8_t* interfaces; 282 uint32_t interfaces_length = 0; 283 uint8_t num_interfaces[1]; 284 285 num_interfaces[0] = 0; 286 287 #if (defined CDC_ENABLED) && defined(HID_ENABLED) 288 num_interfaces[0] += 3; 289 interfaces = (const uint8_t*) CDC_GetInterface(); 290 interfaces_length = CDC_GetInterfaceLength() + HID_GetInterfaceLength(); 291 if( maxlen > CDC_GetInterfaceLength() + HID_GetInterfaceLength() + sizeof(ConfigDescriptor) ) 292 { 293 maxlen = CDC_GetInterfaceLength() + HID_GetInterfaceLength() + sizeof(ConfigDescriptor); 294 } 295 296 #else 297 #ifdef CDC_ENABLED 298 num_interfaces[0] += 2; 299 interfaces = (const uint8_t*) CDC_GetInterface(); 300 interfaces_length += CDC_GetInterfaceLength(); 301 if( maxlen > CDC_GetInterfaceLength()+ sizeof(ConfigDescriptor) ) 302 { 303 maxlen = CDC_GetInterfaceLength()+ sizeof(ConfigDescriptor); 304 } 305 #endif 306 307 #ifdef HID_ENABLED 308 num_interfaces[0] += 1; 309 interfaces = (const uint8_t*) HID_GetInterface(); 310 interfaces_length += HID_GetInterfaceLength(); 311 if( maxlen > HID_GetInterfaceLength()+ sizeof(ConfigDescriptor) ) 312 { 313 maxlen = HID_GetInterfaceLength()+ sizeof(ConfigDescriptor); 314 } 315 #endif 316 #endif 317 318 _Pragma("pack(1)") 319 ConfigDescriptor config = D_CONFIG((uint16_t)(interfaces_length + sizeof(ConfigDescriptor)),num_interfaces[0]); 320 _Pragma("pack()") 321 322 memcpy( cache_buffer, &config, sizeof(ConfigDescriptor) ); 323 324 #if (defined CDC_ENABLED) && defined(HID_ENABLED) 325 for ( i=0; i<CDC_GetInterfaceLength(); i++) 326 { 327 cache_buffer[i+sizeof(ConfigDescriptor)] = interfaces[i]; 328 } 329 interfaces = (const uint8_t*) HID_GetInterface(); 330 for ( i=0; i<HID_GetInterfaceLength(); i++) 331 { 332 cache_buffer[i+sizeof(ConfigDescriptor)+CDC_GetInterfaceLength()] = interfaces[i]; 333 } 334 #else 335 #ifdef HID_ENABLED 336 for ( i=0; i<interfaces_length; i++) 337 { 338 cache_buffer[i+sizeof(ConfigDescriptor)] = interfaces[i]; 339 } 340 #endif 341 342 #ifdef CDC_ENABLED 343 for ( i=0; i<interfaces_length; i++) 344 { 345 cache_buffer[i+sizeof(ConfigDescriptor)] = interfaces[i]; 346 } 347 #endif 348 #endif 349 350 if (maxlen > sizeof(cache_buffer)) 351 { 352 maxlen = sizeof(cache_buffer); 353 } 354 USBD_SendControl(0,cache_buffer, maxlen ); 244 245 total = 0; 246 247 packMessages(true); 248 USBD_SendControl(&config, sizeof(ConfigDescriptor)); 249 USBD_SendInterfaces(&total); 250 packMessages(false); 251 355 252 return true; 356 253 } 357 254 358 static bool USBD_SendDescriptor(Setup* pSetup)359 { 360 uint8_t t = pSetup->wValueH;255 bool USBD_SendDescriptor(Setup &setup) 256 { 257 uint8_t t = setup.wValueH; 361 258 uint8_t desc_length = 0; 362 const uint8_t* desc_addr = 0; 363 364 if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) 365 { 366 TRACE_CORE(printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength);) 367 return USBD_SendConfiguration(pSetup->wLength); 368 } 369 370 #ifdef HID_ENABLED 371 if (HID_REPORT_DESCRIPTOR_TYPE == t) 372 { 373 TRACE_CORE(puts("=> USBD_SendDescriptor : HID_REPORT_DESCRIPTOR_TYPE\r\n");) 374 return HID_GetDescriptor(); 375 } 376 if (HID_HID_DESCRIPTOR_TYPE == t) 377 { 378 uint8_t tab[9] = D_HIDREPORT((uint8_t)HID_SizeReportDescriptor()); 379 380 TRACE_CORE(puts("=> USBD_SendDescriptor : HID_HID_DESCRIPTOR_TYPE\r\n");) 381 382 return USBD_SendControl(0, tab, sizeof(tab)); 383 } 384 #endif 385 386 if (USB_DEVICE_DESCRIPTOR_TYPE == t) 387 { 388 TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");) 389 desc_addr = (const uint8_t*)&USB_DeviceDescriptor; 390 if( *desc_addr > pSetup->wLength ) { 391 desc_length = pSetup->wLength; 392 } 259 bool _cdcComposite; 260 int ret; 261 const uint8_t *desc_addr = 0; 262 263 if (t == USB_CONFIGURATION_DESCRIPTOR_TYPE) 264 { 265 return USBD_SendConfiguration(setup.wLength); 266 } 267 268 if (t == USB_DEVICE_DESCRIPTOR_TYPE) 269 { 270 if (setup.wLength == 8) 271 _cdcComposite = 1; 272 273 desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptor : (const uint8_t*)&USB_DeviceDescriptor; 274 275 if (*desc_addr > setup.wLength) { 276 desc_length = setup.wLength; 277 } 393 278 } 394 279 else if (USB_STRING_DESCRIPTOR_TYPE == t) 395 280 { 396 TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");) 397 if (pSetup->wValueL == 0) { 281 if (setup.wValueL == 0) { 398 282 desc_addr = (const uint8_t*)&STRING_LANGUAGE; 399 283 } 400 else if ( pSetup->wValueL == IPRODUCT) {401 return USB _SendStringDescriptor(STRING_PRODUCT, pSetup->wLength);402 } 403 else if ( pSetup->wValueL == IMANUFACTURER) {404 return USB _SendStringDescriptor(STRING_MANUFACTURER, pSetup->wLength);284 else if (setup.wValueL == IPRODUCT) { 285 return USBD_SendStringDescriptor(STRING_PRODUCT, setup.wLength); 286 } 287 else if (setup.wValueL == IMANUFACTURER) { 288 return USBD_SendStringDescriptor(STRING_MANUFACTURER, setup.wLength); 405 289 } 406 290 else { 407 291 return false; 408 292 } 409 if( *desc_addr > pSetup->wLength ) { 410 desc_length = pSetup->wLength; 411 } 412 } 413 else 414 { 415 TRACE_CORE(printf("Device ERROR");) 416 } 417 418 if (desc_addr == 0) 419 { 293 if (*desc_addr > setup.wLength) { 294 desc_length = setup.wLength; 295 } 296 } 297 else 298 { 299 } 300 301 if (desc_addr == 0) { 420 302 return false; 421 303 } 422 304 423 if (desc_length == 0) 424 { 305 if (desc_length == 0) { 425 306 desc_length = *desc_addr; 426 307 } 427 308 428 TRACE_CORE(printf("=> USBD_SendDescriptor : desc_addr=%p desc_length=%d\r\n", desc_addr, desc_length);) 429 USBD_SendControl(0, desc_addr, desc_length); 309 USBD_SendControl(desc_addr, desc_length); 430 310 431 311 return true; 432 312 } 433 313 434 435 void EndpointHandler(uint8_t bEndpoint) 436 { 314 void initEP(uint32_t ep, uint32_t config) 315 { 316 if (config == (USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0))) 317 { 318 usbd.epBank1SetSize(ep, 64); 319 usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); 320 usbd.epBank1SetType(ep, 4); // INTERRUPT IN 321 } 322 else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0))) 323 { 324 usbd.epBank0SetSize(ep, 64); 325 usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]); 326 usbd.epBank0SetType(ep, 3); // BULK OUT 327 328 // Release OUT EP 329 usbd.epBank0SetMultiPacketSize(ep, 64); 330 usbd.epBank0SetByteCount(ep, 0); 331 } 332 else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0))) 333 { 334 usbd.epBank1SetSize(ep, 64); 335 usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[ep]); 336 337 // NAK on endpoint IN, the bank is not yet filled in. 338 usbd.epBank1ResetReady(ep); 339 340 usbd.epBank1SetType(ep, 3); // BULK IN 341 } 342 else if (config == USB_ENDPOINT_TYPE_CONTROL) 343 { 344 // XXX: Needed? 345 // usbd.epBank0DisableAutoZLP(ep); 346 // usbd.epBank1DisableAutoZLP(ep); 347 348 // Setup Control OUT 349 usbd.epBank0SetSize(ep, 64); 350 usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]); 351 usbd.epBank0SetType(ep, 1); // CONTROL OUT / SETUP 352 353 // Setup Control IN 354 usbd.epBank1SetSize(ep, 64); 355 usbd.epBank1SetAddress(ep, &udd_ep_in_cache_buffer[0]); 356 usbd.epBank1SetType(ep, 1); // CONTROL IN 357 358 // Release OUT EP 359 usbd.epBank0SetMultiPacketSize(ep, 64); 360 usbd.epBank0SetByteCount(ep, 0); 361 362 // NAK on endpoint OUT, the bank is full. 363 usbd.epBank0SetReady(ep); 364 } 365 } 366 367 void sendZlp(uint32_t ep) 368 { 369 // Set the byte count as zero 370 usbd.epBank1SetByteCount(ep, 0); 371 } 372 373 void setAddress(uint32_t addr) 374 { 375 usbd.epBank1SetByteCount(0, 0); 376 usbd.epBank1AckTransferComplete(0); 377 378 // RAM buffer is full, we can send data (IN) 379 usbd.epBank1SetReady(0); 380 381 // Wait for transfer to complete 382 while (!usbd.epBank1IsTransferComplete(0)) {} 383 384 // Set USB address to addr 385 USB->DEVICE.DADD.bit.DADD = addr; // Address 386 USB->DEVICE.DADD.bit.ADDEN = 1; // Enable 387 } 388 389 uint32_t EndPoints[] = 390 { 391 USB_ENDPOINT_TYPE_CONTROL, 392 437 393 #ifdef CDC_ENABLED 438 if( bEndpoint == CDC_ENDPOINT_OUT ) 439 { 440 udd_ack_out_received(CDC_ENDPOINT_OUT); 441 442 // Handle received bytes 394 USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0), // CDC_ENDPOINT_ACM 395 USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0), // CDC_ENDPOINT_OUT 396 USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0), // CDC_ENDPOINT_IN 397 #endif 398 399 }; 400 401 void initEndpoints() { 402 for (uint8_t i = 1; i < sizeof(EndPoints) && EndPoints[i] != 0; i++) { 403 initEP(i, EndPoints[i]); 404 } 405 } 406 407 bool handleStandardSetup(Setup &setup) 408 { 409 switch (setup.bRequest) { 410 case GET_STATUS: 411 if (setup.bmRequestType == 0) // device 412 { 413 // Send the device status 414 // TODO: Check current configuration for power mode (if device is configured) 415 // TODO: Check if remote wake-up is enabled 416 uint8_t buff[] = { 0, 0 }; 417 USBD_armSend(0, buff, 2); 418 return true; 419 } 420 // if( setup.bmRequestType == 2 ) // Endpoint: 421 else 422 { 423 // Send the endpoint status 424 // Check if the endpoint if currently halted 425 uint8_t buff[] = { 0, 0 }; 426 if (isEndpointHalt == 1) 427 buff[0] = 1; 428 USBD_armSend(0, buff, 2); 429 return true; 430 } 431 432 case CLEAR_FEATURE: 433 // Check which is the selected feature 434 if (setup.wValueL == 1) // DEVICEREMOTEWAKEUP 435 { 436 // Enable remote wake-up and send a ZLP 437 uint8_t buff[] = { 0, 0 }; 438 if (isRemoteWakeUpEnabled == 1) 439 buff[0] = 1; 440 USBD_armSend(0, buff, 2); 441 return true; 442 } 443 else // if( setup.wValueL == 0) // ENDPOINTHALT 444 { 445 isEndpointHalt = 0; 446 sendZlp(0); 447 return true; 448 } 449 450 case SET_FEATURE: 451 // Check which is the selected feature 452 if (setup.wValueL == 1) // DEVICEREMOTEWAKEUP 453 { 454 // Enable remote wake-up and send a ZLP 455 isRemoteWakeUpEnabled = 1; 456 uint8_t buff[] = { 0 }; 457 USBD_armSend(0, buff, 1); 458 return true; 459 } 460 if (setup.wValueL == 0) // ENDPOINTHALT 461 { 462 // Halt endpoint 463 isEndpointHalt = 1; 464 sendZlp(0); 465 return true; 466 } 467 468 case SET_ADDRESS: 469 setAddress(setup.wValueL); 470 return true; 471 472 case GET_DESCRIPTOR: 473 return USBD_SendDescriptor(setup); 474 475 case SET_DESCRIPTOR: 476 return false; 477 478 case GET_CONFIGURATION: 479 USBD_armSend(0, (void*)&_usbConfiguration, 1); 480 return true; 481 482 case SET_CONFIGURATION: 483 if (REQUEST_DEVICE == (setup.bmRequestType & REQUEST_RECIPIENT)) { 484 485 initEndpoints(); 486 _usbConfiguration = setup.wValueL; 487 488 #if defined(CDC_ENABLED) 489 // Enable interrupt for CDC reception from host (OUT packet) 490 usbd.epBank1EnableTransferComplete(CDC_ENDPOINT_ACM); 491 usbd.epBank0EnableTransferComplete(CDC_ENDPOINT_OUT); 492 #endif 493 494 sendZlp(0); 495 return true; 496 } else { 497 return false; 498 } 499 500 case GET_INTERFACE: 501 USBD_armSend(0, (void*)&_usbSetInterface, 1); 502 return true; 503 504 case SET_INTERFACE: 505 _usbSetInterface = setup.wValueL; 506 sendZlp(0); 507 return true; 508 509 default: 510 return true; 511 } 512 } 513 514 bool handleClassInterfaceSetup(Setup& setup) 515 { 516 uint8_t i = setup.wIndex; 517 518 #if defined(CDC_ENABLED) 519 if (CDC_ACM_INTERFACE == i) 520 { 521 if (CDC_Setup(setup) == false) { 522 sendZlp(0); 523 } 524 return true; 525 } 526 #endif 527 528 return false; 529 } 530 531 void stall(uint32_t ep) 532 { 533 // TODO: test 534 // TODO: use .bit. notation 535 536 // Stall endpoint 537 USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ(2); 538 } 539 540 void handleEndpoint(uint8_t ep) 541 { 542 #if defined(CDC_ENABLED) 543 if (ep == CDC_ENDPOINT_OUT) 544 { 545 // The RAM Buffer is empty: we can receive data 546 //usbd.epBank0ResetReady(CDC_ENDPOINT_OUT); 547 548 // Handle received bytes 443 549 if (USBD_Available(CDC_ENDPOINT_OUT)) 550 SerialUSB.accept(); 551 } 552 if (ep == CDC_ENDPOINT_IN) 553 { 554 // NAK on endpoint IN, the bank is not yet filled in. 555 usbd.epBank1ResetReady(CDC_ENDPOINT_IN); 556 usbd.epBank1AckTransferComplete(CDC_ENDPOINT_IN); 557 } 558 if (ep == CDC_ENDPOINT_ACM) 559 { 560 // NAK on endpoint IN, the bank is not yet filled in. 561 usbd.epBank1ResetReady(CDC_ENDPOINT_ACM); 562 usbd.epBank1AckTransferComplete(CDC_ENDPOINT_ACM); 563 } 564 #endif 565 566 } 567 568 void ISRHandler() 569 { 570 571 if (_pack_message == true) { 572 return; 573 } 574 // End-Of-Reset 575 if (usbd.isEndOfResetInterrupt()) 576 { 577 // Configure EP 0 578 initEP(0, USB_ENDPOINT_TYPE_CONTROL); 579 580 // Enable Setup-Received interrupt 581 usbd.epBank0EnableSetupReceived(0); 582 583 _usbConfiguration = 0; 584 585 usbd.ackEndOfResetInterrupt(); 586 } 587 588 // Start-Of-Frame 589 if (usbd.isStartOfFrameInterrupt()) 590 { 591 usbd.ackStartOfFrameInterrupt(); 592 } 593 594 // Endpoint 0 Received Setup interrupt 595 if (usbd.epBank0IsSetupReceived(0)) 596 { 597 usbd.epBank0AckSetupReceived(0); 598 599 Setup *setup = reinterpret_cast<Setup *>(udd_ep_out_cache_buffer[0]); 600 601 /* Clear the Bank 0 ready flag on Control OUT */ 602 // The RAM Buffer is empty: we can receive data 603 usbd.epBank0ResetReady(0); 604 605 bool ok; 606 if (REQUEST_STANDARD == (setup->bmRequestType & REQUEST_TYPE)) { 607 // Standard Requests 608 ok = handleStandardSetup(*setup); 609 } else { 610 // Class Interface Requests 611 ok = handleClassInterfaceSetup(*setup); 612 } 613 614 if (ok) { 615 usbd.epBank1SetReady(0); 616 } else { 617 stall(0); 618 } 619 620 if (usbd.epBank1IsStalled(0)) 444 621 { 445 SerialUSB.accept(); 446 } 447 } 448 if( bEndpoint == CDC_ENDPOINT_IN ) 449 { 450 udd_ack_in_received(CDC_ENDPOINT_IN); 451 /* Clear the transfer complete flag */ 452 udd_clear_transf_cplt(CDC_ENDPOINT_IN); 453 454 } 455 if( bEndpoint == CDC_ENDPOINT_ACM ) 456 { 457 udd_ack_in_received(CDC_ENDPOINT_ACM); 458 /* Clear the transfer complete flag */ 459 udd_clear_transf_cplt(CDC_ENDPOINT_ACM); 460 } 461 #endif 462 463 #ifdef HID_ENABLED 464 /* Nothing to do in our example */ 465 #endif 466 } 467 468 469 void USB_Handler(void) 470 { 471 uint16_t flags; 472 uint8_t i; 473 uint8_t ept_int; 474 475 ept_int = udd_endpoint_interrupt(); 622 usbd.epBank1AckStalled(0); 623 624 // Remove stall request 625 usbd.epBank1DisableStalled(0); 626 } 476 627 477 /* Not endpoint interrupt */ 478 if (0 == ept_int) 479 { 480 udd_clear_wakeup_interrupt(); 481 udd_clear_eorsm_interrupt(); 482 udd_clear_suspend_interrupt(); 483 484 // End of bus reset 485 if (Is_udd_reset()) 628 } // end Received Setup handler 629 PORT->Group[0].OUTSET.reg =0x08000000 ; //TxLED off 630 PORT->Group[1].OUTSET.reg =0x00000008 ; //RxLED off 631 632 uint8_t i=0; 633 uint8_t ept_int = usbd.epInterruptSummary() & 0xFE; // Remove endpoint number 0 (setup) 634 while (ept_int != 0) 635 { 636 // Check if endpoint has a pending interrupt 637 if ((ept_int & (1 << i)) != 0) 486 638 { 487 TRACE_CORE(printf(">>> End of Reset\r\n");) 488 // Reset USB address to 0 489 udd_configure_address(0); 490 491 // Configure EP 0 492 UDD_InitEP(0, USB_ENDPOINT_TYPE_CONTROL); 493 udd_enable_setup_received_interrupt(0); 494 _usbConfiguration = 0; 495 udd_ack_reset(); 496 } 497 498 if (Is_udd_sof()) 499 { 500 udd_ack_sof(); 501 } 502 503 } 504 else 505 { 506 // Endpoint interrupt 507 flags = udd_read_endpoint_flag(0); 508 509 // endpoint received setup interrupt 510 if (flags & USB_DEVICE_EPINTFLAG_RXSTP) 511 { 512 Setup *pSetupData; 513 514 /* Clear the Received Setup flag */ 515 udd_read_endpoint_flag(0) = USB_DEVICE_EPINTFLAG_RXSTP; 516 517 UDD_Recv(EP0, (uint8_t**)&pSetupData); 518 519 /* Clear the Bank 0 ready flag on Control OUT */ 520 udd_ack_out_received(0); 521 522 bool ok = true; 523 if (REQUEST_STANDARD == (pSetupData->bmRequestType & REQUEST_TYPE)) 639 // Endpoint Transfer Complete (0/1) Interrupt 640 if (usbd.epBank0IsTransferComplete(i) || 641 usbd.epBank1IsTransferComplete(i)) 524 642 { 525 unsigned char data_to_be_send[2]; 526 527 // Standard Requests 528 uint8_t r = pSetupData->bRequest; 529 if (GET_STATUS == r) 530 { 531 if( pSetupData->bmRequestType == 0 ) // device 532 { 533 // Send the device status 534 TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");) 535 // Check current configuration for power mode (if device is configured) 536 537 // Check if remote wake-up is enabled 538 539 data_to_be_send[0]=0; 540 data_to_be_send[1]=0; 541 UDD_Send(0, data_to_be_send, 2); 542 } 543 // if( pSetupData->bmRequestType == 2 ) // Endpoint: 544 else 545 { 546 // Send the endpoint status 547 // Check if the endpoint if currently halted 548 if( isEndpointHalt == 1 ) 549 data_to_be_send[0]=1; 550 else 551 data_to_be_send[0]=0; 552 data_to_be_send[1]=0; 553 UDD_Send(0, data_to_be_send, 2); 554 } 555 } 556 else if (CLEAR_FEATURE == r) 557 { 558 // Check which is the selected feature 559 if( pSetupData->wValueL == 1) // DEVICEREMOTEWAKEUP 560 { 561 // Enable remote wake-up and send a ZLP 562 if( isRemoteWakeUpEnabled == 1 ) 563 data_to_be_send[0]=1; 564 else 565 data_to_be_send[0]=0; 566 data_to_be_send[1]=0; 567 UDD_Send(0, data_to_be_send, 2); 568 } 569 else // if( pSetupData->wValueL == 0) // ENDPOINTHALT 570 { 571 isEndpointHalt = 0; 572 send_zlp(); 573 } 574 } 575 else if (SET_FEATURE == r) 576 { 577 // Check which is the selected feature 578 if( pSetupData->wValueL == 1) // DEVICEREMOTEWAKEUP 579 { 580 // Enable remote wake-up and send a ZLP 581 isRemoteWakeUpEnabled = 1; 582 data_to_be_send[0] = 0; 583 UDD_Send(0, data_to_be_send, 1); 584 } 585 if( pSetupData->wValueL == 0) // ENDPOINTHALT 586 { 587 // Halt endpoint 588 isEndpointHalt = 1; 589 send_zlp(); 590 } 591 } 592 else if (SET_ADDRESS == r) 593 { 594 TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");) 595 UDD_SetAddress(pSetupData->wValueL); 596 } 597 else if (GET_DESCRIPTOR == r) 598 { 599 TRACE_CORE(puts(">>> EP0 Int: GET_DESCRIPTOR\r\n");) 600 ok = USBD_SendDescriptor(pSetupData); 601 } 602 else if (SET_DESCRIPTOR == r) 603 { 604 TRACE_CORE(puts(">>> EP0 Int: SET_DESCRIPTOR\r\n");) 605 ok = false; 606 } 607 else if (GET_CONFIGURATION == r) 608 { 609 TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");) 610 UDD_Send(0, (void*)&_usbConfiguration, 1); 611 } 612 else if (SET_CONFIGURATION == r) 613 { 614 if (REQUEST_DEVICE == (pSetupData->bmRequestType & REQUEST_RECIPIENT)) 615 { 616 TRACE_CORE(printf(">>> EP0 Int: SET_CONFIGURATION REQUEST_DEVICE %d\r\n", pSetupData->wValueL);) 617 #ifdef HID_ENABLED 618 UDD_InitEP( HID_ENDPOINT_INT, USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0)); 619 #endif 620 621 #ifdef CDC_ENABLED 622 UDD_InitEP( CDC_ENDPOINT_ACM, USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0)); 623 UDD_InitEP( CDC_ENDPOINT_OUT, USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(0)); 624 UDD_InitEP( CDC_ENDPOINT_IN, USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_IN(0)); 625 #endif 626 _usbConfiguration = pSetupData->wValueL; 627 628 #ifdef CDC_ENABLED 629 // Enable interrupt for CDC reception from host (OUT packet) 630 udd_ept_enable_it_transf_cplt_in(CDC_ENDPOINT_ACM); 631 udd_ept_enable_it_transf_cplt_out(CDC_ENDPOINT_OUT); 632 #endif 633 send_zlp(); 634 } 635 else 636 { 637 TRACE_CORE(puts(">>> EP0 Int: SET_CONFIGURATION failed!\r\n");) 638 ok = false; 639 } 640 } 641 else if (GET_INTERFACE == r) 642 { 643 TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");) 644 UDD_Send(0, (void*)&_usbSetInterface, 1); 645 } 646 else if (SET_INTERFACE == r) 647 { 648 _usbSetInterface = pSetupData->wValueL; 649 TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");) 650 send_zlp(); 651 } 643 handleEndpoint(i); 652 644 } 653 else 654 { 655 TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");) 656 ok = USBD_ClassInterfaceRequest(*pSetupData); 657 } 658 659 if (ok) 660 { 661 TRACE_CORE(puts(">>> EP0 Int: Send packet\r\n");) 662 UDD_ClearIN(); 663 } 664 else 665 { 666 TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");) 667 UDD_Stall(0); 668 } 669 670 if( flags & USB_DEVICE_EPINTFLAG_STALL1 ) 671 { 672 /* Clear the stall flag */ 673 udd_clear_stall_request(0); 674 675 // Remove stall request 676 udd_remove_stall_request(0); 677 } 678 } // end if USB_DEVICE_EPINTFLAG_RXSTP 679 680 i=0; 681 ept_int &= 0xFE; // Remove endpoint number 0 (setup) 682 while (ept_int != 0) 683 { 684 // Check if endpoint has a pending interrupt 685 if ((ept_int & (1 << i)) != 0) 686 { 687 if( (udd_read_endpoint_flag(i) & USB_DEVICE_EPINTFLAG_TRCPT_Msk ) != 0 ) 688 689 { 690 EndpointHandler(i); 691 } 692 ept_int &= ~(1 << i); 693 694 if (ept_int != 0) 695 { 696 697 TRACE_CORE("\n\r - "); 698 } 699 } 700 i++; 701 if( i> USB_EPT_NUM) break; // exit 702 } 703 } 704 } 705 645 ept_int &= ~(1 << i); 646 } 647 i++; 648 if (i > USB_EPT_NUM) 649 break; // fire exit 650 } 651 } 652 653 // USB_Handler ISR 654 extern "C" void UDD_Handler(void) { 655 ISRHandler(); 656 } 706 657 707 658 708 659 void USBD_Flush(uint32_t ep) 709 660 { 710 if (UDD_FifoByteCount(ep)) 711 { 712 UDD_ReleaseTX(ep); 713 } 714 } 715 716 // Counting frames 717 uint32_t USBD_Connected(void) 718 { 719 uint8_t f = UDD_GetFrameNumber(); 720 return f != UDD_GetFrameNumber(); 721 } 722 723 724 //======================================================================= 725 //======================================================================= 726 727 USBDevice_ USBDevice; 728 729 USBDevice_::USBDevice_() 730 { 661 if (USBD_Available(ep)) { 662 // RAM buffer is full, we can send data (IN) 663 usbd.epBank1SetReady(ep); 664 665 // Clear the transfer complete flag 666 usbd.epBank1AckTransferComplete(ep); 667 } 668 } 669 670 671 bool connected() 672 { 673 // Count frame numbers 674 uint8_t f = USB->DEVICE.FNUM.bit.FNUM; 675 //delay(3); 676 return f != USB->DEVICE.FNUM.bit.FNUM; 677 } 678 679 uint8_t armRecvCtrlOUT(uint32_t ep) 680 { 681 // Get endpoint configuration from setting register 682 usbd.epBank0SetAddress(ep, &udd_ep_out_cache_buffer[ep]); 683 usbd.epBank0SetMultiPacketSize(ep, 8); 684 usbd.epBank0SetByteCount(ep, 0); 685 686 usbd.epBank0ResetReady(ep); 687 688 // Wait OUT 689 while (!usbd.epBank0IsReady(ep)) {} 690 while (!usbd.epBank0IsTransferComplete(ep)) {} 691 return usbd.epBank0ByteCount(ep); 692 } 693 694 695 uint32_t USBD_RecvControl(void *_data, uint32_t len) 696 { 697 uint8_t *data = reinterpret_cast<uint8_t *>(_data); 698 699 // The RAM Buffer is empty: we can receive data 700 usbd.epBank0ResetReady(0); 701 702 //usbd.epBank0AckSetupReceived(0); 703 uint32_t read = armRecvCtrlOUT(0); 704 if (read > len) 705 read = len; 706 //while (!usbd.epBank0AckTransferComplete(0)) {} 707 uint8_t *buffer = udd_ep_out_cache_buffer[0]; 708 for (uint32_t i=0; i<len; i++) { 709 data[i] = buffer[i]; 710 } 711 712 return read; 713 } 714 715 // Number of bytes, assumes a rx endpoint 716 uint32_t USBD_Available(uint32_t ep) 717 { 718 return usbd.epBank0ByteCount(ep); 719 } 720 721 uint8_t armRecv(uint32_t ep) 722 { 723 uint16_t count = usbd.epBank0ByteCount(ep); 724 if (count >= 64) { 725 usbd.epBank0SetByteCount(ep, count - 64); 726 } else { 727 usbd.epBank0SetByteCount(ep, 0); 728 } 729 return usbd.epBank0ByteCount(ep); 730 } 731 732 // Non Blocking receive 733 // Return number of bytes read 734 uint32_t USBD_Recv(uint32_t ep, void *_data, uint32_t len) 735 { 736 if (!_usbConfiguration) 737 return -1; 738 739 PORT->Group[1].OUTCLR.reg =0x00000008 ; //RxLED on 740 if (USBD_Available(ep) < len) 741 len = USBD_Available(ep); 742 743 armRecv(ep); 744 745 usbd.epBank0DisableTransferComplete(ep); 746 747 memcpy(_data, udd_ep_out_cache_buffer[ep], len); 748 749 // release empty buffer 750 if (len && !USBD_Available(ep)) { 751 // The RAM Buffer is empty: we can receive data 752 usbd.epBank0ResetReady(ep); 753 754 // Clear Transfer complete 0 flag 755 usbd.epBank0AckTransferComplete(ep); 756 } 757 758 return len; 759 } 760 761 // Recv 1 byte if ready 762 uint32_t USBD_Recv(uint32_t ep) 763 { 764 uint8_t c; 765 if (USBD_Recv(ep, &c, 1) != 1) { 766 return -1; 767 } else { 768 return c; 769 } 770 } 771 772 773 774 //================================================================== 775 776 void USBDevice_::init() 777 { 778 // Enable USB clock 779 PM->APBBMASK.reg |= PM_APBBMASK_USB; 780 781 // Set up the USB DP/DN pins 782 PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; 783 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); 784 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u)); 785 PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1; 786 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); 787 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); 788 789 // Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) 790 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6 791 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 792 GCLK_CLKCTRL_CLKEN; 793 while (GCLK->STATUS.bit.SYNCBUSY) 794 ; 795 796 USB_SetHandler(&UDD_Handler); 797 798 // Reset USB Device 799 usbd.reset(); 800 801 usbd.calibrate(); 802 usbd.setUSBDeviceMode(); 803 usbd.runInStandby(); 804 usbd.setFullSpeed(); 805 806 // Configure interrupts 807 NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); 808 NVIC_EnableIRQ((IRQn_Type) USB_IRQn); 809 810 usbd.enable(); 811 812 initialized = true; 731 813 } 732 814 733 815 bool USBDevice_::attach() 734 816 { 735 if (_usbInitialized != 0UL) 736 { 737 UDD_Attach(); 817 if (!initialized) 818 return false; 819 820 usbd.attach(); 821 usbd.enableEndOfResetInterrupt(); 822 usbd.enableStartOfFrameInterrupt(); 823 738 824 _usbConfiguration = 0; 739 825 return true; 740 } 741 else 742 { 743 return false; 744 } 745 } 826 } 827 746 828 747 829 bool USBDevice_::detach() 748 830 { 749 if (_usbInitialized != 0UL) 750 { 751 UDD_Detach(); 752 return true; 753 } 754 else 755 { 831 if (!initialized) 756 832 return false; 757 } 833 usbd.detach(); 834 return true; 758 835 } 759 836 760 837 bool USBDevice_::configured() 761 838 { 762 return _usbConfiguration ;763 } 764 765 void USBDevice_::poll() 766 { 767 } 768 769 void USBDevice_::init() 770 { 771 UDD_Init(); 772 _usbInitialized=1UL; 773 } 839 return _usbConfiguration != 0; 840 } 841 842 843 844 /* 845 * USB Device instance 846 * ------------------- 847 */ 848 849 // USBDevice class instance 850 USBDevice_ USBDevice;
Note:
See TracChangeset
for help on using the changeset viewer.