- Timestamp:
- Apr 30, 2016, 11:29:25 PM (8 years ago)
- Location:
- rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB
- Files:
-
- 1 added
- 3 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/CDC.cpp
r136 r224 1 /* Copyright (c) 2011, Peter Barrett 2 ** 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. 1 /* 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 17 */ 18 /* 19 ** Modified 04/04/2016 by Arduino.org development team 15 20 */ 16 21 … … 20 25 21 26 // Include Atmel headers 22 #include "Arduino.h" 23 #include "sam.h" 24 #include "wiring_constants.h" 25 #include "USBCore.h" 26 #include "USB/USB_device.h" 27 #include "USBDesc.h" 28 #include "USBAPI.h" 29 30 #include "Reset.h" 31 27 #include <Arduino.h> 28 #include <Reset.h> 32 29 33 30 #ifdef CDC_ENABLED 34 31 35 #define CDC_SERIAL_BUFFER_SIZE 6432 #define CDC_SERIAL_BUFFER_SIZE 256 36 33 37 34 /* For information purpose only since RTS is not always handled by the terminal application */ … … 41 38 #define CDC_LINESTATE_READY (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR) 42 39 43 struct ring_buffer 44 { 40 struct ring_buffer { 45 41 uint8_t buffer[CDC_SERIAL_BUFFER_SIZE]; 46 42 volatile uint32_t head; 47 43 volatile uint32_t tail; 44 volatile bool full; 48 45 }; 49 50 ring_buffer cdc_rx_buffer = { { 0 }, 0, 0}; 51 52 typedef struct 53 { 54 uint32_t dwDTERate; 55 uint8_t bCharFormat; 56 uint8_t bParityType; 57 uint8_t bDataBits; 58 uint8_t lineState; 46 ring_buffer cdc_rx_buffer = {{0}, 0, 0, false}; 47 48 typedef struct { 49 uint32_t dwDTERate; 50 uint8_t bCharFormat; 51 uint8_t bParityType; 52 uint8_t bDataBits; 53 uint8_t lineState; 59 54 } LineInfo; 60 55 61 56 _Pragma("pack(1)") 62 static volatile LineInfo _usbLineInfo = { 63 64 0x00,// bCharFormat65 0x00,// bParityType66 0x08,// bDataBits67 0x00// lineState57 static volatile LineInfo _usbLineInfo = { 58 115200, // dWDTERate 59 0x00, // bCharFormat 60 0x00, // bParityType 61 0x08, // bDataBits 62 0x00 // lineState 68 63 }; 69 64 70 static const CDCDescriptor _cdcInterface =71 { 72 #if (defined CDC_ENABLED) && defined(HID_ENABLED) 65 static volatile int32_t breakValue = -1; 66 67 static CDCDescriptor _cdcInterface = { 73 68 D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0), 74 #endif 75 // 76 D_INTERFACE(CDC_ACM_INTERFACE, 1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),77 D_CDCCS( CDC_HEADER, CDC_V1_10 & 0xFF, (CDC_V1_10>>8) & 0x0FF ),// Header (1.10 bcd)78 79 D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT, 6),// SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported80 D_CDCCS(CDC_UNION, CDC_ACM_INTERFACE,CDC_DATA_INTERFACE),// Communication interface is master, data interface is slave 081 D_CDCCS(CDC_CALL_MANAGEMENT, 1,1),// Device handles call management (not)82 D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10),83 84 // 85 D_INTERFACE(CDC_DATA_INTERFACE, 2,CDC_DATA_INTERFACE_CLASS,0,0),86 D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0),87 D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ), USB_ENDPOINT_TYPE_BULK,EPX_SIZE,0)69 70 // CDC communication interface 71 D_INTERFACE(CDC_ACM_INTERFACE, 1, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0), 72 D_CDCCS(CDC_HEADER, CDC_V1_10 & 0xFF, (CDC_V1_10>>8) & 0x0FF), // Header (1.10 bcd) 73 74 D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT, 6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported 75 D_CDCCS(CDC_UNION, CDC_ACM_INTERFACE, CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 76 D_CDCCS(CDC_CALL_MANAGEMENT, 1, 1), // Device handles call management (not) 77 D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_ACM), USB_ENDPOINT_TYPE_INTERRUPT, 0x10, 0x10), 78 79 // CDC data interface 80 D_INTERFACE(CDC_DATA_INTERFACE, 2, CDC_DATA_INTERFACE_CLASS, 0, 0), 81 D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, EPX_SIZE, 0), 82 D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ), USB_ENDPOINT_TYPE_BULK, EPX_SIZE, 0) 88 83 }; 89 84 _Pragma("pack()") 90 85 91 const void* WEAK CDC_GetInterface(void) 92 { 93 return &_cdcInterface; 94 } 95 96 uint32_t WEAK CDC_GetInterfaceLength(void) 97 { 98 return sizeof( _cdcInterface ); 99 } 100 101 bool WEAK CDC_Setup(Setup& setup) 102 { 103 uint8_t r = setup.bRequest; 104 uint8_t requestType = setup.bmRequestType; 86 const void* _CDC_GetInterface(void) 87 { 88 return &_cdcInterface; 89 } 90 91 uint32_t _CDC_GetInterfaceLength(void) 92 { 93 return sizeof(_cdcInterface); 94 } 95 96 int CDC_GetInterface(uint8_t* interfaceNum) 97 { 98 interfaceNum[0] += 2; // uses 2 99 return USBD_SendControl(&_cdcInterface,sizeof(_cdcInterface)); 100 } 101 102 bool CDC_Setup(Setup& pSetup) 103 { 104 uint8_t requestType = pSetup.bmRequestType; 105 uint8_t r = pSetup.bRequest; 105 106 106 107 if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) … … 108 109 if (CDC_GET_LINE_CODING == r) 109 110 { 110 USBD_SendControl( 0,(void*)&_usbLineInfo,7);111 USBD_SendControl((void*)&_usbLineInfo, 7); 111 112 return true; 112 113 } … … 117 118 if (CDC_SET_LINE_CODING == r) 118 119 { 119 while( UDD_FifoByteCount(EP0) <15); 120 //USBD_RecvControl((void*)&_usbLineInfo,7); 121 uint8_t* line = (uint8_t*)&_usbLineInfo; 122 for(uint8_t i = 0; i<7; i++) 123 line[i] = setup.data[i]; 124 return false; 120 USBD_RecvControl((void*)&_usbLineInfo, 7); 125 121 } 126 122 127 123 if (CDC_SET_CONTROL_LINE_STATE == r) 128 124 { 129 _usbLineInfo.lineState = setup.wValueL; 125 _usbLineInfo.lineState = pSetup.wValueL; 126 } 127 128 if (r == CDC_SET_LINE_CODING || r == CDC_SET_CONTROL_LINE_STATE) 129 { 130 130 // auto-reset into the bootloader is triggered when the port, already 131 // open at 1200 bps, is closed. 132 if (1200 == _usbLineInfo.dwDTERate) 131 // open at 1200 bps, is closed. We check DTR state to determine if host 132 // port is open (bit 0 of lineState). 133 if (_usbLineInfo.dwDTERate == 1200 && (_usbLineInfo.lineState & 0x01) == 0) 133 134 { 134 // We check DTR state to determine if host port is open (bit 0 of lineState).135 if ((_usbLineInfo.lineState & 0x01) == 0)136 initiateReset(250);137 else138 135 initiateReset(250); 136 } 137 else 138 { 139 cancelReset(); 139 140 } 140 141 return false; 141 142 } 143 144 if (r == CDC_SEND_BREAK) 145 { 146 breakValue = ((uint16_t)pSetup.wValueH << 8) | pSetup.wValueL; 147 return false; 148 } 142 149 } 143 150 return false; … … 159 166 void Serial_::accept(void) 160 167 { 168 uint8_t buffer[CDC_SERIAL_BUFFER_SIZE]; 169 uint32_t len = USBD_Recv(CDC_ENDPOINT_OUT, &buffer, CDC_SERIAL_BUFFER_SIZE); 170 171 uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0); 172 __disable_irq(); 173 174 ring_buffer *ringBuffer = &cdc_rx_buffer; 175 uint32_t i = ringBuffer->head; 176 177 uint32_t k = 0; 178 while (len > 0 && !ringBuffer->full) { 179 len--; 180 ringBuffer->buffer[i++] = buffer[k++]; 181 i %= CDC_SERIAL_BUFFER_SIZE; 182 if (i == ringBuffer->tail) 183 ringBuffer->full = true; 184 } 185 ringBuffer->head = i; 186 if (enableInterrupts) { 187 __enable_irq(); 188 } 189 } 190 191 int Serial_::available(void) 192 { 161 193 ring_buffer *buffer = &cdc_rx_buffer; 162 uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE; 163 164 // if we should be storing the received character into the location 165 // just before the tail (meaning that the head would advance to the 166 // current location of the tail), we're about to overflow the buffer 167 // and so we don't write the character or advance the head. 168 while (i != buffer->tail) { 169 uint32_t c; 170 if (!USBD_Available(CDC_ENDPOINT_OUT)) { 171 UDD_ReleaseRX(CDC_ENDPOINT_OUT); 172 break; 173 } 174 c = USBD_Recv(CDC_ENDPOINT_OUT); 175 buffer->buffer[buffer->head] = c; 176 buffer->head = i; 177 178 i = (i + 1) % CDC_SERIAL_BUFFER_SIZE; 179 } 180 } 181 182 int Serial_::available(void) 194 if (buffer->full) { 195 return CDC_SERIAL_BUFFER_SIZE; 196 } 197 if (buffer->head == buffer->tail) { 198 USB->DEVICE.DeviceEndpoint[CDC_ENDPOINT_OUT].EPINTENSET.reg = USB_DEVICE_EPINTENCLR_TRCPT(1); 199 } 200 return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE; 201 } 202 203 int Serial_::peek(void) 183 204 { 184 205 ring_buffer *buffer = &cdc_rx_buffer; 185 return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % CDC_SERIAL_BUFFER_SIZE; 186 } 187 188 int Serial_::peek(void) 206 if (buffer->head == buffer->tail && !buffer->full) { 207 return -1; 208 } else { 209 return buffer->buffer[buffer->tail]; 210 } 211 } 212 213 214 // if the ringBuffer is empty: try to fill it 215 // if it's still empty: return -1 216 // else return the last char 217 // so the buffer is filled only when needed 218 int Serial_::read(void) 189 219 { 190 220 ring_buffer *buffer = &cdc_rx_buffer; 191 221 192 if (buffer->head == buffer->tail)193 {194 return -1;195 }196 else197 {198 return buffer->buffer[buffer->tail];199 }200 }201 202 int Serial_::read(void)203 {204 ring_buffer *buffer = &cdc_rx_buffer;205 206 222 // if the head isn't ahead of the tail, we don't have any characters 207 if (buffer->head == buffer->tail) 223 if (buffer->head == buffer->tail && !buffer->full) 224 { 225 if (USBD_Available(CDC_ENDPOINT_OUT)) 226 accept(); 227 } 228 if (buffer->head == buffer->tail && !buffer->full) 208 229 { 209 230 return -1; … … 213 234 unsigned char c = buffer->buffer[buffer->tail]; 214 235 buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE; 215 if (USBD_Available(CDC_ENDPOINT_OUT)) 216 accept(); 236 buffer->full = false; 217 237 return c; 218 238 } … … 231 251 bytes sent before the user opens the connection or after 232 252 the connection is closed are lost - just like with a UART. */ 233 253 if (_usbLineInfo.lineState > 0) // Problem with Windows(R) 234 254 { 235 255 uint32_t r = USBD_Send(CDC_ENDPOINT_IN, buffer, size); 236 256 237 if (r > 0) 238 { 257 if (r == 0) { 239 258 return r; 240 } else 241 { 259 } else { 242 260 setWriteError(); 243 261 return 0; 244 262 } 245 }263 } 246 264 setWriteError(); 247 265 return 0; … … 259 277 // We add a short delay before returning to fix a bug observed by Federico 260 278 // where the port is configured (lineState != 0) but not quite opened. 261 262 279 Serial_::operator bool() 263 280 { … … 277 294 } 278 295 279 Serial_ SerialUSB; 296 int32_t Serial_::readBreak() { 297 uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0); 298 299 // disable interrupts, 300 // to avoid clearing a breakValue that might occur 301 // while processing the current break value 302 __disable_irq(); 303 304 int32_t ret = breakValue; 305 306 breakValue = -1; 307 308 if (enableInterrupts) { 309 // re-enable the interrupts 310 __enable_irq(); 311 } 312 313 return ret; 314 } 315 316 unsigned long Serial_::baud() { 317 return _usbLineInfo.dwDTERate; 318 } 319 320 uint8_t Serial_::stopbits() { 321 return _usbLineInfo.bCharFormat; 322 } 323 324 uint8_t Serial_::paritytype() { 325 return _usbLineInfo.bParityType; 326 } 327 328 uint8_t Serial_::numbits() { 329 return _usbLineInfo.bDataBits; 330 } 331 332 bool Serial_::dtr() { 333 return _usbLineInfo.lineState & 0x1; 334 } 335 336 bool Serial_::rts() { 337 return _usbLineInfo.lineState & 0x2; 338 } 339 340 Serial_ SerialUSB(USBDevice); 280 341 281 342 #endif -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/HID.cpp
r136 r224 21 21 #include "USBDesc.h" 22 22 #include "sam.h" 23 #include "USB/USB_device.h"24 23 25 24 … … 45 44 // HID report descriptor 46 45 _Pragma("pack(1)") 47 extern const uint 8_t _hidReportDescriptor[] = {46 extern const uint32_t _hidReportDescriptor[] = { 48 47 // Mouse 49 48 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 … … 162 161 uint32_t WEAK HID_GetDescriptor(void) 163 162 { 164 return USBD_SendControl( 0,_hidReportDescriptor,sizeof(_hidReportDescriptor));163 return USBD_SendControl(_hidReportDescriptor,sizeof(_hidReportDescriptor)); 165 164 } 166 165 … … 197 196 if (HID_GET_IDLE == r) 198 197 { 199 U DD_Send(0, &_hid_idle, 1);200 U DD_ClearIN();198 USBD_Send(0, &_hid_idle, 1); 199 USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY; 201 200 return true; 202 201 } -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBAPI.h
r136 r224 1 1 /* 2 Copyright (c) 201 2 Arduino. All right reserved.2 Copyright (c) 2015 Arduino LLC. All right reserved. 3 3 4 4 This library is free software; you can redistribute it and/or … … 16 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 17 */ 18 19 #ifndef __USBAPI__ 20 #define __USBAPI__ 21 22 23 /* Define attribute */ 24 #if defined ( __CC_ARM ) /* Keil uVision 4 */ 25 #define WEAK (__attribute__ ((weak))) 26 #elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ 27 #define WEAK __weak 28 #elif defined ( __GNUC__ ) /* GCC CS */ 29 #define WEAK __attribute__ ((weak)) 30 #endif 31 18 /* 19 **Modified 04/04/2016 by Arduino.org development team 20 */ 21 22 #pragma once 23 24 #define WEAK __attribute__ ((weak)) 25 26 #define HSTPIPCFG_PTYPE_BLK 1 27 #define HSTPIPCFG_PTOKEN_IN 2 28 #define HSTPIPCFG_PTOKEN_OUT 3 29 #define HSTPIPCFG_PBK_1_BANK 4 30 #define HSTPIPCFG_PTYPE_INTRPT 5 31 32 #define EP0 0 33 #define EPX_SIZE 64 // 64 for Full Speed, EPT size max is 1024 32 34 33 35 #if defined __cplusplus … … 37 39 38 40 //================================================================================ 39 //================================================================================ 40 // USB 41 42 class USBDevice_ 43 { 44 public: 45 USBDevice_(); 41 // USB 42 //================================================================================ 43 //================================================================================ 44 // Low level API 45 typedef struct { 46 union { 47 uint8_t bmRequestType; 48 struct { 49 uint8_t direction : 5; 50 uint8_t type : 2; 51 uint8_t transferDirection : 1; 52 }; 53 }; 54 uint8_t bRequest; 55 uint8_t wValueL; 56 uint8_t wValueH; 57 uint16_t wIndex; 58 uint16_t wLength; 59 } Setup; 60 61 62 class USBDevice_ { 63 public: 64 USBDevice_() {}; 65 66 // USB Device API 67 void init(); 68 bool attach(); // Serial port goes down too... 69 bool detach(); 70 46 71 bool configured(); 47 72 48 bool attach(); 49 bool detach(); // Serial port goes down too... 50 void poll(); 51 void init(); 52 }; 73 private: 74 bool initialized; 75 }; 76 53 77 extern USBDevice_ USBDevice; 54 78 55 79 //================================================================================ 56 //================================================================================57 80 // Serial over CDC (Serial1 is the physical port) 58 81 59 82 class Serial_ : public Stream 60 83 { 61 private: 62 RingBuffer *_cdc_rx_buffer; 63 public: 84 public: 85 Serial_(USBDevice_ &_usb) : usb(_usb) { } 64 86 void begin(uint32_t baud_count); 65 87 void begin(unsigned long, uint8_t); … … 75 97 using Print::write; // pull in write(str) from Print 76 98 operator bool(); 99 100 // This method allows processing "SEND_BREAK" requests sent by 101 // the USB host. Those requests indicate that the host wants to 102 // send a BREAK signal and are accompanied by a single uint16_t 103 // value, specifying the duration of the break. The value 0 104 // means to end any current break, while the value 0xffff means 105 // to start an indefinite break. 106 // readBreak() will return the value of the most recent break 107 // request, but will return it at most once, returning -1 when 108 // readBreak() is called again (until another break request is 109 // received, which is again returned once). 110 // This also mean that if two break requests are received 111 // without readBreak() being called in between, the value of the 112 // first request is lost. 113 // Note that the value returned is a long, so it can return 114 // 0-0xffff as well as -1. 115 int32_t readBreak(); 116 117 // These return the settings specified by the USB host for the 118 // serial port. These aren't really used, but are offered here 119 // in case a sketch wants to act on these settings. 120 uint32_t baud(); 121 uint8_t stopbits(); 122 uint8_t paritytype(); 123 uint8_t numbits(); 124 bool dtr(); 125 bool rts(); 126 enum { 127 ONE_STOP_BIT = 0, 128 ONE_AND_HALF_STOP_BIT = 1, 129 TWO_STOP_BITS = 2, 130 }; 131 enum { 132 NO_PARITY = 0, 133 ODD_PARITY = 1, 134 EVEN_PARITY = 2, 135 MARK_PARITY = 3, 136 SPACE_PARITY = 4, 137 }; 138 139 private: 140 USBDevice_ &usb; 141 RingBuffer *_cdc_rx_buffer; 77 142 }; 78 143 extern Serial_ SerialUSB; … … 171 236 //================================================================================ 172 237 //================================================================================ 173 // Low level API174 175 typedef struct176 {177 uint8_t bmRequestType;178 uint8_t bRequest;179 uint8_t wValueL;180 uint8_t wValueH;181 uint16_t wIndex;182 uint16_t wLength;183 uint8_t data[8];184 } Setup;185 186 //================================================================================187 //================================================================================188 238 // HID 'Driver' 189 239 … … 202 252 uint32_t MSC_GetInterface(uint8_t* interfaceNum); 203 253 uint32_t MSC_GetDescriptor(uint32_t i); 204 bool MSC_Setup(Setup& setup);254 bool MSC_Setup(Setup& pSetup); 205 255 bool MSC_Data(uint8_t rx,uint8_t tx); 206 256 … … 209 259 // CDC 'Driver' 210 260 211 const void* CDC_GetInterface(/*uint8_t* interfaceNum*/); 212 uint32_t WEAK CDC_GetInterfaceLength(void); 261 int CDC_GetInterface(uint8_t* interfaceNum); 262 const void* _CDC_GetInterface(void); 263 uint32_t _CDC_GetInterfaceLength(void); 213 264 uint32_t CDC_GetOtherInterface(uint8_t* interfaceNum); 214 265 uint32_t CDC_GetDescriptor(uint32_t i); 215 bool CDC_Setup(Setup& setup); 216 217 //================================================================================ 218 //================================================================================ 219 220 uint32_t USBD_SendControl(uint8_t flags, const void* d, uint32_t len); 266 bool CDC_Setup(Setup& pSetup); 267 268 269 //================================================================================ 270 //================================================================================ 271 272 uint32_t USBD_SendControl(const void* _data, uint32_t len); 221 273 uint32_t USBD_RecvControl(void* d, uint32_t len); 274 void USBD_Calibrate(); 222 275 uint32_t USBD_SendInterfaces(void); 223 276 bool USBD_ClassInterfaceRequest(Setup& setup); … … 228 281 uint32_t USBD_Recv(uint32_t ep, void* data, uint32_t len); // non-blocking 229 282 uint32_t USBD_Recv(uint32_t ep); // non-blocking 283 uint8_t USBD_armRecv(uint32_t ep); 230 284 void USBD_Flush(uint32_t ep); 231 285 uint32_t USBD_Connected(void); 232 286 233 287 #endif // __cplusplus 234 #endif // __USBAPI__ -
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; -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBCore.h
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) 2014 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 16 22 17 23 #ifndef __USBCORE_H__ … … 30 36 #define SET_INTERFACE 11 31 37 38 // bEndpointAddress in Endpoint Descriptor 39 #define USB_ENDPOINT_DIRECTION_MASK 0x80 40 #define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) 41 #define USB_ENDPOINT_IN(addr) ((addr) | 0x80) 42 43 #define USB_ENDPOINTS 7 44 45 #define USB_ENDPOINT_TYPE_MASK 0x03 46 #define USB_ENDPOINT_TYPE_CONTROL 0x00 47 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 48 #define USB_ENDPOINT_TYPE_BULK 0x02 49 #define USB_ENDPOINT_TYPE_INTERRUPT 0x03 32 50 33 51 // bmRequestType … … 47 65 #define REQUEST_RECIPIENT 0x1F 48 66 49 #define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE) 50 #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE) 67 #define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE) 68 #define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE) 69 #define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE) 51 70 52 71 // Class requests … … 55 74 #define CDC_GET_LINE_CODING 0x21 56 75 #define CDC_SET_CONTROL_LINE_STATE 0x22 76 #define CDC_SEND_BREAK 0x23 57 77 58 78 #define MSC_RESET 0xFF … … 108 128 #define MSC_SUBCLASS_SCSI 0x06 109 129 #define MSC_PROTOCOL_BULK_ONLY 0x50 110 111 #define HID_HID_DESCRIPTOR_TYPE 0x21112 #define HID_REPORT_DESCRIPTOR_TYPE 0x22113 #define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23114 115 #define TX_RX_LED_PULSE_MS 100 //----- Tx & Rx led blinking during transmission (declaration)116 130 117 131 _Pragma("pack(1)") … … 225 239 typedef struct 226 240 { 227 #if (defined CDC_ENABLED) && defined(HID_ENABLED)228 241 // IAD 229 242 IADDescriptor iad; // Only needed on compound device 230 #endif231 243 // Control 232 244 InterfaceDescriptor cif; … … 249 261 EndpointDescriptor out; 250 262 } MSCDescriptor; 263 251 264 252 265 typedef struct … … 273 286 274 287 #define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ 275 { 18, 1, 0x 110, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }288 { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } 276 289 /* Table 9-8. Standard Device Descriptor 277 290 * bLength, bDescriptorType, bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0, … … 279 292 280 293 #define D_CONFIG(_totalLength,_interfaces) \ 281 { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_ SELF_POWERED, USB_CONFIG_POWER_MA(500) }294 { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } 282 295 /* Table 9-10. Standard Configuration Descriptor 283 296 * bLength, bDescriptorType, wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration 284 297 * bmAttributes, bMaxPower */ 285 298 286 299 #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ 287 300 { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } … … 289 302 * bLength, bDescriptorType, bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass, 290 303 * bInterfaceSubClass, bInterfaceProtocol, iInterface */ 291 304 292 305 #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ 293 306 { 7, 5, _addr,_attr,_packetSize, _interval } … … 297 310 #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ 298 311 { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } 299 /* iadclasscode_r10.pdf, Table 9 Z. Standard Interface Association Descriptor312 /* iadclasscode_r10.pdf, Table 9\96Z. Standard Interface Association Descriptor 300 313 * bLength, bDescriptorType, bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction */ 301 314 #define D_HIDREPORT(_descriptorLength) \ … … 303 316 /* HID1_11.pdf E.8 HID Descriptor (Mouse) 304 317 * bLength, bDescriptorType, bcdHID, bCountryCode, bNumDescriptors, bDescriptorType, wItemLength */ 305 318 306 319 // Functional Descriptor General Format 307 320 #define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBDesc.h
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) 2014 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 17 */ 18 /* 19 **Modified 04/04/2016 by Arduino.org development team 15 20 */ 16 21 … … 22 27 #define HID_ENABLED 23 28 29 30 #ifdef CDC_ENABLED 31 #define CDC_INTERFACE_COUNT 2 32 #define CDC_ENPOINT_COUNT 3 33 #endif 34 24 35 // CDC 25 36 #define CDC_ACM_INTERFACE 0 // CDC ACM 26 37 #define CDC_DATA_INTERFACE 1 // CDC Data 38 #define CDC_FIRST_ENDPOINT 1 27 39 #define CDC_ENDPOINT_ACM 1 28 40 #define CDC_ENDPOINT_OUT 2 29 41 #define CDC_ENDPOINT_IN 3 42 43 #ifdef CDC_ENABLED 44 #define CDC_RX CDC_ENDPOINT_OUT 45 #define CDC_TX CDC_ENDPOINT_IN 46 #endif 30 47 31 48 // HID … … 33 50 #define HID_ENDPOINT_INT 4 34 51 52 53 #define ISERIAL_MAX_LEN 20 54 35 55 // Defined string description 36 56 #define IMANUFACTURER 1 37 #define IPRODUCT 2 57 #define IPRODUCT 2 58 #define ISERIAL 3 38 59 39 60 #endif /* __USBDESC_H__ */ -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USB_host.h
r136 r224 1 /* ---------------------------------------------------------------------------- 2 * SAM Software Package License 3 * ---------------------------------------------------------------------------- 4 * Copyright (c) 2011-2012, Atmel Corporation 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following condition is met: 10 * 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the disclaimer below. 13 * 14 * Atmel's name may not be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ---------------------------------------------------------------------------- 28 */ 1 /* 2 Copyright (c) 2014 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 17 */ 18 /* 19 **Modified 04/04/2016 by Arduino.org development team 20 */ 29 21 30 22 #ifndef USB_HOST_H_INCLUDED … … 32 24 33 25 #include <stdint.h> 34 26 #include "samd21_host.h" 35 27 #ifdef __cplusplus 36 28 extern "C" { 37 29 #endif 38 30 39 #define tokSETUP U OTGHS_HSTPIPCFG_PTOKEN_SETUP40 #define tokIN U OTGHS_HSTPIPCFG_PTOKEN_IN41 #define tokOUT U OTGHS_HSTPIPCFG_PTOKEN_OUT42 #define tokINHS U OTGHS_HSTPIPCFG_PTOKEN_IN43 #define tokOUTHS U OTGHS_HSTPIPCFG_PTOKEN_OUT31 #define tokSETUP USB_HOST_PCFG_PTOKEN_SETUP 32 #define tokIN USB_HOST_PCFG_PTOKEN_IN 33 #define tokOUT USB_HOST_PCFG_PTOKEN_OUT 34 #define tokINHS USB_HOST_PCFG_PTOKEN_IN 35 #define tokOUTHS USB_HOST_PCFG_PTOKEN_OUT 44 36 45 37 //! \brief Device speed … … 58 50 } uhd_vbus_state_t; 59 51 60 //extern uhd_speed_t uhd_get_speed(void);61 62 extern void UHD_SetStack(void (*pf_isr)(void));63 52 extern void UHD_Init(void); 64 extern void UHD_BusReset(void); 53 extern void UHD_Handler(void); 54 extern void USB_SetHandler(void (*pf_isr)(void)); 65 55 extern uhd_vbus_state_t UHD_GetVBUSState(void); 66 56 extern uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size); 67 57 extern uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank); 58 extern void UHD_Pipe_CountZero(uint32_t ul_pipe); 68 59 extern void UHD_Pipe_Free(uint32_t ul_pipe); 69 60 extern uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data); -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c
r136 r224 1 /* ---------------------------------------------------------------------------- 2 * SAM Software Package License 3 * ---------------------------------------------------------------------------- 4 * Copyright (c) 2011-2012, Atmel Corporation 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following condition is met: 10 * 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the disclaimer below. 13 * 14 * Atmel's name may not be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ---------------------------------------------------------------------------- 28 */ 1 /* 2 Copyright (c) 2014 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 17 */ 18 /* 19 ** Modified 04/04/2016 by Arduino.org development team 20 */ 21 22 29 23 30 24 #include <stdio.h> 25 #include <stdint.h> 26 #include <string.h> 27 28 #include "../Arduino.h" 29 #include "variant.h" 30 #include "USB_host.h" 31 #include "samd21_host.h" 32 #include "sam.h" 33 #include "wiring_digital.h" 34 #include "wiring_private.h" 35 36 #define HOST_DEFINED 31 37 32 38 #ifdef HOST_DEFINED … … 35 41 #define TRACE_UOTGHS_HOST(x) 36 42 37 //extern void (*gpf_isr)(void);38 39 43 // Handle UOTGHS Host driver state 40 44 static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS; 41 45 42 __attribute__((__aligned__(4))) UsbHostDescriptor usb_pipe_table[USB_EPT_NUM]; 46 __attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM]; 47 48 extern void (*gpf_isr)(void); 43 49 44 50 45 51 // NVM Software Calibration Area Mapping 46 52 // USB TRANSN calibration value. Should be written to the USB PADCAL register. 47 #define NVM_USB_PAD_TRANSN_POS 4548 #define NVM_USB_PAD_TRANSN_SIZE 553 #define NVM_USB_PAD_TRANSN_POS 45 54 #define NVM_USB_PAD_TRANSN_SIZE 5 49 55 // USB TRANSP calibration value. Should be written to the USB PADCAL register. 50 #define NVM_USB_PAD_TRANSP_POS 5051 #define NVM_USB_PAD_TRANSP_SIZE 556 #define NVM_USB_PAD_TRANSP_POS 50 57 #define NVM_USB_PAD_TRANSP_SIZE 5 52 58 // USB TRIM calibration value. Should be written to the USB PADCAL register. 53 #define NVM_USB_PAD_TRIM_POS 55 54 #define NVM_USB_PAD_TRIM_SIZE 3 59 #define NVM_USB_PAD_TRIM_POS 55 60 #define NVM_USB_PAD_TRIM_SIZE 3 61 62 static void UHD_ISR(void); 55 63 56 64 /** … … 60 68 { 61 69 uint32_t pad_transn; 62 uint32_t pad_transp; 63 uint32_t pad_trim; 70 uint32_t pad_transp; 71 uint32_t pad_trim; 72 uint32_t i; 73 74 // USB_SetHandler(&USB_Handler); 75 USB_SetHandler(&UHD_ISR); 64 76 65 77 /* Enable USB clock */ 66 78 PM->APBBMASK.reg |= PM_APBBMASK_USB; 67 79 68 /* Set up the USB DP/DN pins */ 69 PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; 70 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); 71 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u)); 72 PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1; 73 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); 74 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); 80 /* Set up the USB DP/DM pins */ 81 pinPeripheral( 33ul, PIO_COM ); 82 pinPeripheral( 34ul, PIO_COM ); 75 83 76 84 /* ---------------------------------------------------------------------------------------------- 77 78 79 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) |// Generic Clock Multiplexer 680 GCLK_CLKCTRL_GEN_GCLK0 |// Generic Clock Generator 0 is source81 GCLK_CLKCTRL_CLKEN;82 83 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY)84 { 85 /* Wait for synchronization */85 * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) 86 */ 87 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6 88 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 89 GCLK_CLKCTRL_CLKEN; 90 91 while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) 92 { 93 /* Wait for synchronization */ 86 94 } 87 95 88 96 /* Reset */ 89 97 USB->HOST.CTRLA.bit.SWRST = 1; 90 while (USB->HOST.SYNCBUSY.bit.SWRST) { 98 while (USB->HOST.SYNCBUSY.bit.SWRST) 99 { 91 100 /* Sync wait */ 92 101 } 93 102 94 udd_enable(); 103 // uhd_enable(); 104 USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE | USB_CTRLA_MODE; 105 uhd_force_host_mode(); 106 while (USB->HOST.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE); 95 107 96 108 /* Load Pad Calibration */ 97 pad_transn =( *((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller 98 + (NVM_USB_PAD_TRANSN_POS / 32)) 99 >> (NVM_USB_PAD_TRANSN_POS % 32)) 100 & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); 101 102 if (pad_transn == 0x1F) { // maximum value (31) 109 pad_transn = (*((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller 110 + (NVM_USB_PAD_TRANSN_POS / 32)) 111 >> (NVM_USB_PAD_TRANSN_POS % 32)) 112 & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); 113 114 if (pad_transn == 0x1F) // maximum value (31) 115 { 103 116 pad_transn = 5; 104 117 } … … 106 119 USB->HOST.PADCAL.bit.TRANSN = pad_transn; 107 120 108 pad_transp =( *((uint32_t *)(NVMCTRL_OTP4) 109 + (NVM_USB_PAD_TRANSP_POS / 32)) 110 >> (NVM_USB_PAD_TRANSP_POS % 32)) 111 & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); 112 113 if (pad_transp == 0x1F) { // maximum value (31) 121 pad_transp = (*((uint32_t *)(NVMCTRL_OTP4) 122 + (NVM_USB_PAD_TRANSP_POS / 32)) 123 >> (NVM_USB_PAD_TRANSP_POS % 32)) 124 & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); 125 126 if (pad_transp == 0x1F) // maximum value (31) 127 { 114 128 pad_transp = 29; 115 129 } … … 117 131 USB->HOST.PADCAL.bit.TRANSP = pad_transp; 118 132 119 pad_trim =( *((uint32_t *)(NVMCTRL_OTP4) 120 + (NVM_USB_PAD_TRIM_POS / 32)) 121 >> (NVM_USB_PAD_TRIM_POS % 32)) 122 & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); 123 124 if (pad_trim == 0x7) { // maximum value (7) 133 pad_trim = (*((uint32_t *)(NVMCTRL_OTP4) 134 + (NVM_USB_PAD_TRIM_POS / 32)) 135 >> (NVM_USB_PAD_TRIM_POS % 32)) 136 & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); 137 138 if (pad_trim == 0x7) // maximum value (7) 139 { 125 140 pad_trim = 3; 126 141 } … … 128 143 USB->HOST.PADCAL.bit.TRIM = pad_trim; 129 144 145 130 146 /* Set the configuration */ 131 u dd_force_host_mode();132 udd_device_run_in_standby();133 // Set address of USB SRAM 134 USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]);135 // For USB_SPEED_FULL136 udd_force_full_speed();137 for (uint32_t i = 0; i < sizeof(usb_endpoint_table); i++){138 (*(uint32_t *)(&usb_endpoint_table[0]+i)) = 0;139 147 uhd_run_in_standby(); 148 // Set address of USB SRAM 149 USB->HOST.DESCADD.reg = (uint32_t)(&usb_pipe_table[0]); 150 // For USB_SPEED_FULL 151 uhd_force_full_speed(); 152 for (i = 0; i < sizeof(usb_pipe_table); i++) 153 { 154 (*(uint32_t *)(&usb_pipe_table[0] + i)) = 0; 155 } 140 156 141 157 uhd_state = UHD_STATE_NO_VBUS; 142 158 159 // Put VBUS on USB port 160 pinMode( 32ul, OUTPUT ); 161 digitalWrite( 32ul, HIGH ); 162 163 uhd_enable_connection_int(); 164 165 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DCONN; 166 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_WAKEUP; 167 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DDISC; 168 143 169 USB->HOST.CTRLB.bit.VBUSOK = 1; 144 170 145 171 // Configure interrupts 146 NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); 147 NVIC_EnableIRQ((IRQn_Type) USB_IRQn); 148 } 149 150 //static void UHD_ISR(void) 151 void USB_Handler(void) 152 { 153 uint16_t flags; 154 uint8_t i; 155 uint8_t ept_int; 156 157 ept_int = udd_endpoint_interrupt(); 158 159 /* Not endpoint interrupt */ 160 if (0 == ept_int) 161 { 162 163 164 } 165 else 166 { 167 /* host interrupts */ 172 NVIC_SetPriority((IRQn_Type)USB_IRQn, 0UL); 173 NVIC_EnableIRQ((IRQn_Type)USB_IRQn); 174 } 175 176 177 static void UHD_ISR(void) 178 //void USB_Handler(void) 179 { 180 uint16_t flags; 181 182 if (USB->HOST.CTRLA.bit.MODE) { 183 /*host mode ISR */ 168 184 169 185 /* get interrupt flags */ … … 171 187 172 188 /* host SOF interrupt */ 173 if (flags & USB_HOST_INTFLAG_HSOF) { 189 if (flags & USB_HOST_INTFLAG_HSOF) 190 { 174 191 /* clear the flag */ 175 192 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_HSOF; 176 uhd_state = UHD_STATE_CONNECTED;193 uhd_state = UHD_STATE_CONNECTED; 177 194 return; 178 195 } 179 196 180 197 /* host reset interrupt */ 181 if (flags & USB_HOST_INTFLAG_RST) { 198 if (flags & USB_HOST_INTFLAG_RST) 199 { 182 200 /* clear the flag */ 183 201 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST; 184 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;202 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 185 203 return; 186 204 } 187 205 188 206 /* host upstream resume interrupts */ 189 if (flags & USB_HOST_INTFLAG_UPRSM) { 207 if (flags & USB_HOST_INTFLAG_UPRSM) 208 { 190 209 /* clear the flags */ 191 210 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_UPRSM; 192 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;211 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 193 212 return; 194 213 } 195 214 196 215 /* host downstream resume interrupts */ 197 if (flags & USB_HOST_INTFLAG_DNRSM) { 216 if (flags & USB_HOST_INTFLAG_DNRSM) 217 { 198 218 /* clear the flags */ 199 219 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DNRSM; 200 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;220 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 201 221 return; 202 222 } 203 223 204 224 /* host wakeup interrupts */ 205 if (flags & USB_HOST_INTFLAG_WAKEUP) { 225 if (flags & USB_HOST_INTFLAG_WAKEUP) 226 { 206 227 /* clear the flags */ 207 228 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_WAKEUP; 208 uhd_state = UHD_STATE_CONNECTED;//UHD_STATE_ERROR;229 uhd_state = UHD_STATE_CONNECTED; //UHD_STATE_ERROR; 209 230 return; 210 231 } 211 232 212 233 /* host ram access interrupt */ 213 if (flags & USB_HOST_INTFLAG_RAMACER) { 234 if (flags & USB_HOST_INTFLAG_RAMACER) 235 { 214 236 /* clear the flag */ 215 237 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RAMACER; 216 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;238 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 217 239 return; 218 240 } 219 241 220 242 /* host connect interrupt */ 221 if (flags & USB_HOST_INTFLAG_DCONN) { 222 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");) 243 if (flags & USB_HOST_INTFLAG_DCONN) 244 { 245 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n"); 246 ) 223 247 /* clear the flag */ 224 248 uhd_ack_connection(); … … 231 255 } 232 256 233 /* host disconnect interrupt */ 234 if (flags & USB_HOST_INTFLAG_DDISC) { 235 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");) 257 /* host disconnect interrupt */ 258 if (flags & USB_HOST_INTFLAG_DDISC) 259 { 260 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n"); 261 ) 236 262 /* clear the flag */ 237 263 uhd_ack_disconnection(); … … 246 272 return; 247 273 } 248 249 } 250 251 } 252 253 254 255 256 /** 257 * \brief Trigger a USB bus reset. 258 */ 259 void UHD_BusReset(void) 260 { 261 USB->HOST.CTRLB.bit.BUSRESET = 1;; 262 } 274 } 275 else { 276 while(1); 277 } 278 } 279 280 263 281 264 282 /** … … 269 287 uhd_vbus_state_t UHD_GetVBUSState(void) 270 288 { 271 return uhd_state; 272 } 273 289 return uhd_state; 290 } 274 291 275 292 … … 283 300 * \retval 1 error. 284 301 */ 285 uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size) 286 { 287 struct usb_host_pipe_config cfg; 288 289 if (ep_size < 8) 290 { 291 return 0; 292 } 293 294 /* set pipe config */ 295 USB->HOST.HostPipe[0].PCFG.bit.BK = 0; 296 USB->HOST.HostPipe[0].PCFG.bit.PTYPE = USB_HOST_PIPE_TYPE_CONTROL; 297 USB->HOST.HostPipe[0].BINTERVAL.reg = 0; 298 USB->HOST.HostPipe[0].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_SETUP; 299 300 memset((uint8_t *)&usb_pipe_table[pipe_num], 0, sizeof(usb_pipe_table[0])); 301 usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PDADDR = 0; 302 usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0; 303 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03; // 64 bytes 304 305 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; 306 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR; 307 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TXSTP; 308 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL; 309 310 return 1; 311 } 302 uint32_t UHD_Pipe0_Alloc(uint32_t ul_add , uint32_t ul_ep_size) 303 { 304 (void)(ul_add); // Unused argument 305 306 if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) ) 307 ul_ep_size = USB_PCKSIZE_SIZE_8_BYTES; // Low Speed 308 else 309 ul_ep_size = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed 310 311 USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL; 312 usb_pipe_table[0].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0; 313 usb_pipe_table[0].HostDescBank[0].PCKSIZE.bit.SIZE = ul_ep_size; 314 315 return 0; 316 } 317 312 318 313 319 /** … … 336 342 { 337 343 /* set pipe config */ 338 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK = ul_nb_bank; 339 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTYPE = ul_type; 340 USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg = ul_interval; 341 342 if (ul_dir & USB_EP_DIR_IN) 343 { 344 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN; 345 USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 346 } 344 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK = ul_nb_bank; 345 USB->HOST.HostPipe[ul_dev_ep].PCFG.reg &= ~USB_HOST_PCFG_MASK; // USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL; 346 USB->HOST.HostPipe[ul_dev_ep].PCFG.reg |= ul_type; 347 USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg = ul_interval; 348 349 if (ul_dir & USB_EP_DIR_IN) 350 { 351 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN; 352 USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 353 } 354 else 355 { 356 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_OUT; 357 USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 358 } 359 360 if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) ) 361 ul_maxsize = USB_PCKSIZE_SIZE_8_BYTES; // Low Speed 347 362 else 348 { 349 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT; 350 USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 351 } 352 353 memset((uint8_t *)&usb_descriptor_table.usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep])); 354 355 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr; 356 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep; 357 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03; // 64 bytes 358 359 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; 360 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR; 361 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL; 362 363 return 1; 364 } 365 363 ul_maxsize = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed 364 365 memset((uint8_t *)&usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep])); 366 367 usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr; 368 usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep; 369 usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE = ul_maxsize; 370 371 return 1; 372 } 373 374 375 void UHD_Pipe_CountZero(uint32_t ul_pipe) 376 { 377 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 378 } 366 379 367 380 /** … … 372 385 void UHD_Pipe_Free(uint32_t ul_pipe) 373 386 { 374 // Unalloc pipe 375 uhd_disable_pipe(ul_pipe); 376 uhd_unallocate_memory(ul_pipe); 377 uhd_reset_pipe(ul_pipe); 378 379 // The Pipe is frozen and no additional requests will be sent to the device on this pipe address. 380 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 381 } 387 // The Pipe is frozen and no additional requests will be sent to the device on this pipe address. 388 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 389 } 390 382 391 383 392 /** … … 390 399 * \return number of data read. 391 400 */ 392 uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t* buf) 393 { 394 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE) 395 { 396 return 0; 397 } 398 399 /* get pipe config from setting register */ 400 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 401 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 402 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size; 403 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN; 404 405 /* Start transfer */ 406 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 407 408 // Unfreeze pipe 409 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 410 411 return buf_size; 412 } 401 uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t *buf) 402 { 403 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PTYPE_DIS) 404 { 405 return 0; 406 } 407 408 /* get pipe config from setting register */ 409 usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 410 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 411 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size; 412 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN; 413 414 /* Start transfer */ 415 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 416 417 // Unfreeze pipe 418 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 419 420 return buf_size; 421 } 422 413 423 414 424 /** … … 419 429 * \param data Buffer containing data to write. 420 430 */ 421 void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data) 422 { 423 424 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE) 425 { 426 return 0; 427 } 428 429 /* get pipe config from setting register */ 430 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 431 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = buf_size; 432 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 433 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT; 434 435 436 return 1; 431 void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t *buf) 432 { 433 /* get pipe config from setting register */ 434 usb_pipe_table[ul_pipe].HostDescBank[0].ADDR.reg = (uint32_t)buf; 435 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = ul_size; 436 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 437 437 } 438 438 … … 445 445 void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type) 446 446 { 447 /* Start transfer */ 448 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 449 447 USB->HOST.HostPipe[ul_pipe].PCFG.bit.PTOKEN = ul_token_type; 448 449 /* Start transfer */ 450 if(ul_token_type == USB_HOST_PCFG_PTOKEN_SETUP ) 451 { 452 USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TXSTP; 453 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 454 } 455 else if(ul_token_type == USB_HOST_PCFG_PTOKEN_IN ) 456 { 457 USB->HOST.HostPipe[ul_pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 458 } 459 else 460 { 461 USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT(1); // Transfer Complete 0 462 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 463 } 464 450 465 // Unfreeze pipe 451 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 452 } 466 uhd_unfreeze_pipe(ul_pipe); 467 } 468 469 #define USB_HOST_PINTFLAG_TRCPT_Pos 0 /**< \brief (USB_HOST_PINTFLAG) Transfer Complete 0/1 Interrupt Flag */ 470 #define USB_HOST_PINTFLAG_TRCPT_Msk (0x3u << USB_HOST_PINTFLAG_TRCPT_Pos) 471 #define USB_HOST_PINTFLAG_TRCPT(value) ((USB_HOST_PINTFLAG_TRCPT_Msk & ((value) << USB_HOST_PINTFLAG_TRCPT_Pos))) 453 472 454 473 /** … … 463 482 uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type) 464 483 { 465 466 // Freeze pipe 467 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 468 switch(uhd_ctrl_request_phase) { 469 case UHD_CTRL_REQ_PHASE_DATA_IN: 470 _uhd_ctrl_phase_data_in(p_callback_para->transfered_size); 471 break; 472 case UHD_CTRL_REQ_PHASE_ZLP_IN: 473 _uhd_ctrl_request_end(UHD_TRANS_NOERROR); 474 break; 475 case UHD_CTRL_REQ_PHASE_DATA_OUT: 476 _uhd_ctrl_phase_data_out(); 477 break; 478 case UHD_CTRL_REQ_PHASE_ZLP_OUT: 479 _uhd_ctrl_request_end(UHD_TRANS_NOERROR); 480 break; 481 } 482 return 0; 483 } 484 485 #endif 486 484 // Check for transfer completion depending on token type 485 switch (ul_token_type) 486 { 487 case USB_HOST_PCFG_PTOKEN_SETUP: 488 if (Is_uhd_setup_ready(ul_pipe)) 489 { 490 uhd_ack_setup_ready(ul_pipe); 491 uhd_freeze_pipe(ul_pipe); 492 return 1; 493 } 494 break; 495 496 case USB_HOST_PCFG_PTOKEN_IN: 497 if (Is_uhd_in_received(ul_pipe)) 498 { 499 // IN packet received 500 uhd_ack_in_received(ul_pipe); 501 // Freeze will stop after the transfer 502 uhd_freeze_pipe(ul_pipe); 503 return 1; 504 } 505 break; 506 507 case USB_HOST_PCFG_PTOKEN_OUT: 508 if (Is_uhd_out_ready(ul_pipe)) 509 { 510 // OUT packet sent 511 uhd_ack_out_ready(ul_pipe); 512 uhd_freeze_pipe(ul_pipe); 513 return 1; 514 } 515 break; 516 } 517 518 return 0; 519 } 520 521 #endif // HOST_DEFINED -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.h
r136 r224 1 /* ---------------------------------------------------------------------------- 2 * SAM Software Package License 3 * ---------------------------------------------------------------------------- 4 * Copyright (c) 2011-2012, Atmel Corporation 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following condition is met: 10 * 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the disclaimer below. 13 * 14 * Atmel's name may not be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ---------------------------------------------------------------------------- 28 */ 1 /* 2 Copyright (c) 2014 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 17 */ 18 /* 19 **Modified 04/04/2016 by Arduino.org development team 20 */ 29 21 30 22 #ifndef UOTGHS_HOST_H_INCLUDED 31 23 #define UOTGHS_HOST_H_INCLUDED 32 33 24 34 25 #ifdef __cplusplus … … 36 27 #endif 37 28 38 //! \ingroup usb_host_group 39 //! \defgroup uhd_group USB Host Driver (UHD) 40 //! UOTGHS low-level driver for USB host mode 41 //! 42 //! @{ 29 extern __attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM]; 43 30 44 //! @name UOTGHS Host IP properties 45 //! 46 //! @{ 47 //! Get maximal number of endpoints 48 #define uhd_get_pipe_max_nbr() (9) 49 #define UOTGHS_EPT_NUM (uhd_get_pipe_max_nbr()+1) 50 //! @} 31 #define USB_EP_DIR_IN 0x80 // USB_SETUP_DEVICE_TO_HOST 32 #define USB_EP_DIR_OUT 0x00 // USB_SETUP_HOST_TO_DEVICE 51 33 52 //! @name Host Vbus line control 53 //! 54 //! VBOF is an optional output pin which allows to enable or disable 55 //! the external VBus generator. 56 //! 57 //! @{ 58 //! Enables hardware control of USB_VBOF output pin when a Vbus error occur 59 #define uhd_enable_vbus_error_hw_control() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC)) 60 //! Disables hardware control of USB_VBOF output pin when a Vbus error occur 61 #define uhd_disable_vbus_error_hw_control() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC)) 34 #define USB_HOST_PTYPE_DIS USB_HOST_PCFG_PTYPE(0x0) // Pipe is disabled 35 #define USB_HOST_PTYPE_CTRL USB_HOST_PCFG_PTYPE(0x1) // Pipe is enabled and configured as CONTROL 36 #define USB_HOST_PTYPE_ISO USB_HOST_PCFG_PTYPE(0x2) // Pipe is enabled and configured as ISO 37 #define USB_HOST_PTYPE_BULK USB_HOST_PCFG_PTYPE(0x3) // Pipe is enabled and configured as BULK 38 #define USB_HOST_PTYPE_INT USB_HOST_PCFG_PTYPE(0x4) // Pipe is enabled and configured as INTERRUPT 39 #define USB_HOST_PTYPE_EXT USB_HOST_PCFG_PTYPE(0x5) // Pipe is enabled and configured as EXTENDED 62 40 63 //! Pin and function for USB_VBOF according to configuration from USB_VBOF 64 #define USB_VBOF_PIN USB_VBOF_GPIO 65 #define USB_VBOF_FUNCTION USB_VBOF_FLAGS 66 //! Output USB_VBOF onto its pin 67 #define uhd_output_vbof_pin() do {\ 68 pio_configure_pin(USB_VBOF_PIN, USB_VBOF_FUNCTION); \ 69 } while (0) 41 #define USB_HOST_NB_BK_1 1 70 42 71 //! Set USB_VBOF output pin polarity 72 #define uhd_set_vbof_active_high() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO)) 73 #define uhd_set_vbof_active_low() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO)) 74 //! Requests VBus activation 75 #define uhd_enable_vbus() (Set_bits(UOTGHS->UOTGHS_SFR, UOTGHS_SR_VBUSRQ)) 76 //! Requests VBus deactivation 77 #define uhd_disable_vbus() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SR_VBUSRQ)) 78 //! Tests if VBus activation has been requested 79 #define Is_uhd_vbus_enabled() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSRQ)) 80 //! @} 43 #define USB_HOST_PCFG_PTOKEN_SETUP USB_HOST_PCFG_PTOKEN(0x0) 44 #define USB_HOST_PCFG_PTOKEN_IN USB_HOST_PCFG_PTOKEN(0x1) 45 #define USB_HOST_PCFG_PTOKEN_OUT USB_HOST_PCFG_PTOKEN(0x2) 81 46 82 //! @name Host Vbus line monitoring 83 //! 84 //! The VBus level is always checked by USBC hardware. 85 //! 86 //! @{ 87 #define uhd_enable_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) 88 #define uhd_disable_vbus_error_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) 89 #define Is_uhd_vbus_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE)) 90 #define uhd_ack_vbus_error_interrupt() (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SCR_VBERRIC)) 91 #define Is_uhd_vbus_error_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBERRI)) 92 //! @} 47 #define USB_ERRORFLOW USB_HOST_STATUS_BK_ERRORFLOW 48 #define USB_ERRORTIMEOUT USB_HOST_STATUS_PIPE_TOUTER 49 #define USB_ERROR_DATATOGGLE USB_HOST_STATUS_PIPE_DTGLER 93 50 94 #define uhd_ack_errors_interrupt() (UOTGHS->UOTGHS_SCR = (UOTGHS_SCR_VBERRIC|UOTGHS_SCR_BCERRIC|UOTGHS_SCR_HNPERRIC|UOTGHS_SCR_STOIC)) 95 #define Is_uhd_errors_interrupt() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE|UOTGHS_CTRL_BCERRE|UOTGHS_CTRL_HNPERRE|UOTGHS_CTRL_STOE)) 96 #define uhd_enable_suspend_error_interrupt() 97 #define uhd_enable_hnp_error_interrupt() 98 #define uhd_enable_bconn_error_interrupt() 51 #define USB_PCKSIZE_SIZE_8_BYTES 0 52 #define USB_PCKSIZE_SIZE_16_BYTES 1 53 #define USB_PCKSIZE_SIZE_32_BYTES 2 54 #define USB_PCKSIZE_SIZE_64_BYTES 3 55 #define USB_PCKSIZE_SIZE_128_BYTES 4 56 #define USB_PCKSIZE_SIZE_256_BYTES 5 57 #define USB_PCKSIZE_SIZE_512_BYTES 6 58 #define USB_PCKSIZE_SIZE_1023_BYTES_FS 7 59 #define USB_PCKSIZE_SIZE_1024_BYTES_HS 7 99 60 100 //! @name USB device connection/disconnection monitoring 101 //! @{ 102 #define uhd_enable_connection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DCONNIES) 103 #define uhd_disable_connection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DCONNIEC) 104 #define Is_uhd_connection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DCONNIE)) 105 #define uhd_ack_connection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC) 106 #define Is_uhd_connection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DCONNI)) 61 #define USB_HOST_DTGL(p) (USB->HOST.HostPipe[p].PSTATUS.reg & USB_HOST_PSTATUS_DTGL)>>USB_HOST_PSTATUS_DTGL_Pos 107 62 108 #define uhd_enable_disconnection_int() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DDISCIES) 109 #define uhd_disable_disconnection_int() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DDISCIEC) 110 #define Is_uhd_disconnection_int_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DDISCIE)) 111 #define uhd_ack_disconnection() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DDISCIC) 112 #define Is_uhd_disconnection() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DDISCI)) 113 //! @} 63 // USB host connection/disconnection monitoring 64 #define uhd_enable_connection_int() USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DCONN 65 #define uhd_disable_connection_int() USB->HOST.INTENCLR.reg = USB_HOST_INTENCLR_DCONN 66 #define uhd_ack_connection() USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DCONN 114 67 115 //! @name USB device speed control 116 //! @{ 117 #define uhd_get_speed_mode() (Rd_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk)) 118 #define Is_uhd_low_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_LOW_SPEED) 119 #define Is_uhd_full_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_FULL_SPEED) 120 #define Is_uhd_high_speed_mode() (uhd_get_speed_mode() == UOTGHS_SR_SPEED_HIGH_SPEED) 121 //! Enable high speed mode 122 # define uhd_enable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_HIGH_SPEED)) 123 //! Disable high speed mode 124 # define uhd_disable_high_speed_mode() (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_FORCED_FS)) 125 //! @} 68 #define uhd_enable_disconnection_int() USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DDISC 69 #define uhd_disable_disconnection_int() USB->HOST.INTENCLR.reg = USB_HOST_INTENCLR_DDISC 70 #define uhd_ack_disconnection() USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DDISC 126 71 127 //! @name Bus events control 128 //! These macros manage the bus events: reset, SOF, resume, wakeup. 129 //! @{ 72 // Initiates a USB register reset 73 #define uhd_start_USB_reg_reset() USB->HOST.CTRLA.bit.SWRST = 1; 130 74 131 //! Initiates a reset event 132 //! @{ 133 #define uhd_start_reset() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) 134 #define Is_uhd_starting_reset() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) 135 #define uhd_stop_reset() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET)) 75 // Bus Reset 76 #define Is_uhd_starting_reset() (USB->HOST.CTRLB.bit.BUSRESET == 1) 77 #define UHD_BusReset() USB->HOST.CTRLB.bit.BUSRESET = 1 78 #define uhd_stop_reset() // nothing to do 136 79 137 #define uhd_enable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSTIES) 138 #define uhd_disable_reset_sent_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSTIEC) 139 #define Is_uhd_reset_sent_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSTIE)) 140 #define uhd_ack_reset_sent() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSTIC) 141 #define Is_uhd_reset_sent() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSTI)) 142 //! @} 80 #define uhd_ack_reset_sent() USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST 81 #define Is_uhd_reset_sent() (USB->HOST.INTFLAG.reg & USB_HOST_INTFLAG_RST) 143 82 144 //! Initiates a SOF events 145 //! @{ 146 #define uhd_enable_sof() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) 147 #define uhd_disable_sof() (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) 148 #define Is_uhd_sof_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE)) 149 #define uhd_get_sof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_FNUM_Msk)>>UOTGHS_HSTFNUM_FNUM_Pos) 150 #define uhd_get_microsof_number() ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_MFNUM_Msk)>>UOTGHS_HSTFNUM_MFNUM_Pos) 151 #define uhd_get_frame_position() (Rd_bits(UOTGHS->UOTGHS_HSTFNUM, UOTGHS_HSTFNUM_FLENHIGH_Msk)) 152 #define uhd_enable_sof_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HSOFIES) 153 #define uhd_disable_sof_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HSOFIEC) 154 #define Is_uhd_sof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HSOFIE)) 155 #define uhd_ack_sof() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HSOFIC) 156 #define Is_uhd_sof() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HSOFI)) 157 //! @} 83 // Initiates a SOF events 84 #define uhd_enable_sof() USB->HOST.CTRLB.bit.SOFE = 1 85 #define uhd_disable_sof() USB->HOST.CTRLB.bit.SOFE = 0 86 #define Is_uhd_sof_enabled() (USB->HOST.CTRLB & USB_HOST_CTRLB_SOFE) 87 #define Is_uhd_sof() (USB->HOST.INTFLAG.reg & USB_HOST_INTFLAG_HSOF) 158 88 159 //! Initiates a resume event 160 //! It is called downstream resume event. 161 //! @{ 162 #define uhd_send_resume() (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME)) 163 #define Is_uhd_sending_resume() (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME)) 89 // USB address of pipes 90 #define uhd_configure_address(pipe_num, addr) usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PDADDR = addr 91 #define uhd_get_configured_address(pipe_num) usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PDADDR 164 92 165 #define uhd_enable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSMEDIES) 166 #define uhd_disable_downstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSMEDIEC) 167 #define Is_uhd_downstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSMEDIE)) 168 #define uhd_ack_downstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSMEDIC) 169 #define Is_uhd_downstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSMEDI)) 170 //! @} 93 // Pipes 94 #define uhd_freeze_pipe(p) USB->HOST.HostPipe[p].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE 95 #define uhd_unfreeze_pipe(p) USB->HOST.HostPipe[p].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE 96 #define Is_uhd_pipe_frozen(p) ((USB->HOST.HostPipe[p].PSTATUS.reg&USB_HOST_PSTATUS_PFREEZE)==USB_HOST_PSTATUS_PFREEZE) 171 97 172 //! Detection of a wake-up event 173 //! A wake-up event is received when the host controller is in the suspend mode: 174 //! - and an upstream resume from the peripheral is detected. 175 //! - and a peripheral disconnection is detected. 176 //! @{ 177 #define uhd_enable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HWUPIES) 178 #define uhd_disable_wakeup_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC) 179 #define Is_uhd_wakeup_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HWUPIE)) 180 #define uhd_ack_wakeup() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HWUPIC) 181 #define Is_uhd_wakeup() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HWUPI)) 98 // Pipe configuration 99 #define uhd_configure_pipe_token(p, token) USB->HOST.HostPipe[p].PCFG.bit.PTOKEN = token 182 100 183 #define uhd_enable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RXRSMIES) 184 #define uhd_disable_upstream_resume_interrupt() (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RXRSMIEC) 185 #define Is_uhd_upstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RXRSMIE)) 186 #define uhd_ack_upstream_resume() (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RXRSMIC) 187 #define Is_uhd_upstream_resume() (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RXRSMI)) 188 //! @} 189 //! @} 101 // Pipe data management 102 #define uhd_byte_count(p) usb_pipe_table[p].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT 103 #define uhd_ack_setup_ready(p) USB->HOST.HostPipe[p].PINTFLAG.reg = USB_HOST_PINTFLAG_TXSTP 104 #define Is_uhd_setup_ready(p) ((USB->HOST.HostPipe[p].PINTFLAG.reg&USB_HOST_PINTFLAG_TXSTP) == USB_HOST_PINTFLAG_TXSTP) 105 #define uhd_ack_in_received(p) USB->HOST.HostPipe[p].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT(1) 106 #define Is_uhd_in_received(p) ((USB->HOST.HostPipe[p].PINTFLAG.reg&USB_HOST_PINTFLAG_TRCPT(1)) == USB_HOST_PINTFLAG_TRCPT(1)) 107 #define uhd_ack_out_ready(p) USB->HOST.HostPipe[p].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT(1) 108 #define Is_uhd_out_ready(p) ((USB->HOST.HostPipe[p].PINTFLAG.reg&USB_HOST_PINTFLAG_TRCPT(1)) == USB_HOST_PINTFLAG_TRCPT(1)) 109 #define uhd_ack_nak_received(p) usb_pipe_table[p].HostDescBank[1].STATUS_BK.reg &= ~USB_HOST_STATUS_BK_ERRORFLOW 110 #define Is_uhd_nak_received(p) (usb_pipe_table[p].HostDescBank[1].STATUS_BK.reg & USB_HOST_STATUS_BK_ERRORFLOW) 190 111 112 // Endpoint Interrupt Summary 113 #define uhd_endpoint_interrupt() USB->HOST.PINTSMRY.reg 191 114 192 //! @name Pipes management 193 //! @{ 115 // Run in Standby 116 #define uhd_run_in_standby() USB->HOST.CTRLA.reg |= USB_CTRLA_RUNSTDBY 117 // Force host mode 118 #define uhd_force_host_mode() USB->HOST.CTRLA.reg |= USB_CTRLA_MODE 194 119 195 //! USB address of pipes 196 //! @{ 197 #define uhd_configure_address(p, addr) \ 198 (Wr_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \ 199 UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3), addr)) 200 #define uhd_get_configured_address(p) \ 201 (Rd_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \ 202 UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3))) 203 //! @} 120 // Enable USB macro 121 #define uhd_enable() USB->HOST.CTRLA.reg |= USB_CTRLA_ENABLE 122 // Disable USB macro 123 #define uhd_disable() USB->HOST.CTRLA.reg &= ~USB_CTRLA_ENABLE 204 124 205 //! Pipe enable 206 //! Enable, disable, reset, freeze 207 //! @{ 208 #define uhd_enable_pipe(p) \ 209 (Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) 210 #define uhd_disable_pipe(p) \ 211 (Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) 212 #define Is_uhd_pipe_enabled(p) \ 213 (Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) 214 #define uhd_reset_pipe(p) \ 215 (Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))); \ 216 (Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) 217 #define Is_uhd_resetting_pipe(p) \ 218 (Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))) 219 #define uhd_freeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PFREEZES) 220 #define uhd_unfreeze_pipe(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PFREEZEC) 221 #define Is_uhd_pipe_frozen(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PFREEZE)) 222 #define uhd_reset_data_toggle(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RSTDTS) 223 #define Is_uhd_data_toggle_reset(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RSTDT)) 224 //! @} 225 226 //! Pipe configuration 227 //! @{ 228 #define uhd_configure_pipe_int_req_freq(p,freq) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk, (freq))) 229 #define uhd_get_pipe_int_req_freq(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk)) 230 #define uhd_configure_pipe_endpoint_number(p,ep) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PEPNUM_Msk, (ep))) 231 #define uhd_get_pipe_endpoint_address(p) \ 232 (uhd_is_pipe_in(p) ?\ 233 (uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_IN) :\ 234 (uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_OUT)) 235 #define uhd_get_pipe_endpoint_number(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PEPNUM_Msk))) 236 #define uhd_configure_pipe_type(p, type) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk, type)) 237 #define uhd_get_pipe_type(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk)) 238 #define uhd_enable_pipe_bank_autoswitch(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) 239 #define uhd_disable_pipe_bank_autoswitch(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) 240 #define Is_uhd_pipe_bank_autoswitch_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW)) 241 #define uhd_configure_pipe_token(p, token) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk, token)) 242 #define uhd_get_pipe_token(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk)) 243 #define uhd_is_pipe_in(p) (UOTGHS_HSTPIPCFG_PTOKEN_IN==uhd_get_pipe_token(p)) 244 #define uhd_is_pipe_out(p) (UOTGHS_HSTPIPCFG_PTOKEN_OUT==uhd_get_pipe_token(p)) 245 //! Bounds given integer size to allowed range and rounds it up to the nearest 246 //! available greater size, then applies register format of UOTGHS controller 247 //! for pipe size bit-field. 248 #define uhd_format_pipe_size(size) \ 249 (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3) 250 #define uhd_configure_pipe_size(p,size) \ 251 (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PSIZE_Msk, uhd_format_pipe_size(size))) 252 #define uhd_get_pipe_size(p) (8<<((Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PSIZE_Msk)))>> UOTGHS_HSTPIPCFG_PSIZE_Pos)) 253 #define uhd_configure_pipe_bank(p,bank) (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk, (bank))) 254 #define uhd_get_pipe_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk)) 255 #define uhd_allocate_memory(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) 256 #define uhd_unallocate_memory(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) 257 #define Is_uhd_memory_allocated(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC)) 258 259 //! Enable PING management only available in HS mode 260 # define uhd_enable_ping(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PINGEN)) 261 //#endif 262 #define uhd_configure_pipe(p, freq, ep_num, type, token, size, bank, bank_switch) \ 263 (UOTGHS->UOTGHS_HSTPIPCFG[p] = \ 264 (bank)|\ 265 ((uhd_format_pipe_size(size)<<UOTGHS_HSTPIPCFG_PSIZE_Pos)&UOTGHS_HSTPIPCFG_PSIZE_Msk)|\ 266 ((token)&UOTGHS_HSTPIPCFG_PTOKEN_Msk)|\ 267 ((type)&UOTGHS_HSTPIPCFG_PTYPE_Msk)|\ 268 (((ep_num)<<UOTGHS_HSTPIPCFG_PEPNUM_Pos)&UOTGHS_HSTPIPCFG_PEPNUM_Msk)|\ 269 bank_switch |\ 270 (((freq)<<UOTGHS_HSTPIPCFG_INTFRQ_Pos)&UOTGHS_HSTPIPCFG_INTFRQ_Msk)) 271 272 #define Is_uhd_pipe_configured(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CFGOK)) 273 //! @} 274 275 //! Pipe main interrupts management 276 //! @{ 277 #define uhd_enable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIER = (UOTGHS_HSTIER_PEP_0 << (p))) 278 #define uhd_disable_pipe_interrupt(p) (UOTGHS->UOTGHS_HSTIDR = (UOTGHS_HSTIDR_PEP_0 << (p))) 279 #define Is_uhd_pipe_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_PEP_0 << (p))) 280 #define Is_uhd_pipe_interrupt(p) (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_PEP_0 << (p))) 281 //! returns the lowest pipe number generating a pipe interrupt or UOTGHS_EPT_NUM if none 282 #define uhd_get_interrupt_pipe_number() \ 283 (ctz(((UOTGHS->UOTGHS_HSTISR >> 8) & (UOTGHS->UOTGHS_HSTIMR >> 8)) | (1 << UOTGHS_EPT_NUM))) 284 //! @} 285 286 //! Pipe overflow and underflow for isochronous and interrupt endpoints 287 //! @{ 288 #define uhd_enable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_OVERFIES) 289 #define uhd_disable_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_OVERFIEC) 290 #define Is_uhd_overflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_OVERFIE)) 291 #define uhd_ack_overflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_OVERFIC) 292 #define Is_uhd_overflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_OVERFI)) 293 294 #define uhd_enable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_UNDERFIES) 295 #define uhd_disable_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_UNDERFIEC) 296 #define Is_uhd_underflow_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_UNDERFIE)) 297 #define uhd_ack_underflow_interrupt(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_UNDERFIC) 298 #define Is_uhd_underflow(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_UNDERFI)) 299 //! @} 300 301 //! USB packet errors management 302 //! @{ 303 #define uhd_enable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXSTALLDES) 304 #define uhd_disable_stall_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXSTALLDEC) 305 #define Is_uhd_stall_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXSTALLDE)) 306 #define uhd_ack_stall(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXSTALLDIC) 307 #define Is_uhd_stall(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXSTALLDI)) 308 309 #define uhd_enable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PERRES) 310 #define uhd_disable_pipe_error_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PERREC) 311 #define Is_uhd_pipe_error_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PERRE)) 312 #define uhd_ack_all_errors(p) (UOTGHS->UOTGHS_HSTPIPERR[p] = 0UL) 313 #define Is_uhd_pipe_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PERRI)) 314 #define uhd_error_status(p) (UOTGHS->UOTGHS_HSTPIPERR[p]) 315 #define Is_uhd_bad_data_toggle(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATATGL)) 316 #define Is_uhd_data_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATAPID)) 317 #define Is_uhd_pid_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_PID)) 318 #define Is_uhd_timeout_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_TIMEOUT)) 319 #define Is_uhd_crc16_error(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_CRC16)) 320 #define uhd_get_error_counter(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_COUNTER)) 321 //! @} 322 323 //! Pipe data management 324 //! @{ 325 #define uhd_data_toggle(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_DTSEQ)) 326 327 #define uhd_enable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NBUSYBKES) 328 #define uhd_disable_bank_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NBUSYBKEC) 329 #define Is_uhd_bank_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NBUSYBKE)) 330 #define uhd_nb_busy_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NBUSYBK_Msk)) 331 #define uhd_current_bank(p) (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CURRBK_Msk )) 332 333 #define uhd_enable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_SHORTPACKETES) 334 #define uhd_disable_short_packet_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_SHORTPACKETIEC) 335 #define Is_uhd_short_packet_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_SHORTPACKETIE)) ) 336 #define uhd_ack_short_packet(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_SHORTPACKETIC) 337 #define Is_uhd_short_packet(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_SHORTPACKETI)) 338 #define uhd_byte_count(p) (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PBYCT_Msk)) 339 340 #define Is_uhd_fifocon(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_FIFOCON)) 341 #define uhd_ack_fifocon(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_FIFOCONC) 342 343 #define uhd_enable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXSTPES) 344 #define uhd_disable_setup_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXSTPEC) 345 #define Is_uhd_setup_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXSTPE)) 346 #define uhd_ack_setup_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXSTPIC) 347 #define Is_uhd_setup_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXSTPI)) 348 349 #define uhd_enable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXINES) 350 #define uhd_disable_in_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXINEC) 351 #define Is_uhd_in_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXINE)) 352 #define uhd_ack_in_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXINIC) 353 #define Is_uhd_in_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXINI)) 354 355 #define uhd_enable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXOUTES) 356 #define uhd_disable_out_ready_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXOUTEC) 357 #define Is_uhd_out_ready_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXOUTE)) 358 #define uhd_ack_out_ready(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXOUTIC) 359 #define Is_uhd_out_ready(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXOUTI)) 360 #define uhd_raise_out_ready(p) (UOTGHS->UOTGHS_HSTPIPIFR[p] = UOTGHS_HSTPIPIFR_TXOUTIS) 361 362 #define uhd_enable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NAKEDES) 363 #define uhd_disable_nak_received_interrupt(p) (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NAKEDEC) 364 #define Is_uhd_nak_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NAKEDE)) 365 #define uhd_ack_nak_received(p) (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_NAKEDIC) 366 #define Is_uhd_nak_received(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NAKEDI)) 367 368 #define Is_uhd_read_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL)) 369 #define Is_uhd_write_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL )) 370 371 #define uhd_enable_continuous_in_mode(p) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) 372 #define uhd_disable_continuous_in_mode(p) (Clr_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) 373 #define Is_uhd_continuous_in_mode_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE)) 374 375 #define uhd_in_request_number(p, in_num) (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], (in_num)-1)) 376 #define uhd_get_in_request_number(p) (((Rd_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INRQ_Msk))>>UOTGHS_HSTPIPINRQ_INRQ_Pos)+1) 377 //! @} 378 379 //! Maximum transfer size on USB DMA 380 #define UHD_PIPE_MAX_TRANS 0x8000 381 382 //! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected pipe. 383 //! @param p Target Pipe number 384 //! @param scale Data scale in bits: 64, 32, 16 or 8 385 //! @return Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register 386 //! @warning It is up to the user of this macro to make sure that all accesses 387 //! are aligned with their natural boundaries except 64-bit accesses which 388 //! require only 32-bit alignment. 389 //! @warning It is up to the user of this macro to make sure that used HSB 390 //! addresses are identical to the DPRAM internal pointer modulo 32 bits. 391 #define uhd_get_pipe_fifo_access(p, scale) \ 392 (((volatile TPASTE2(U, scale) (*)[UHD_PIPE_MAX_TRANS / ((scale) / 8)])UOTGHS_RAM_ADDR)[(p)]) 393 125 // Force full speed mode 126 #define uhd_force_full_speed() USB->HOST.CTRLB.reg &= ~USB_HOST_CTRLB_SPDCONF_Msk 394 127 395 128 #ifdef __cplusplus
Note:
See TracChangeset
for help on using the changeset viewer.