Ignore:
Timestamp:
Apr 30, 2016, 11:29:25 PM (8 years ago)
Author:
ertl-honda
Message:

1.7.10のファイルに更新

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
    1520*/
    1621
     
    2025
    2126// 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>
    3229
    3330#ifdef CDC_ENABLED
    3431
    35 #define CDC_SERIAL_BUFFER_SIZE  64
     32#define CDC_SERIAL_BUFFER_SIZE  256
    3633
    3734/* For information purpose only since RTS is not always handled by the terminal application */
     
    4138#define CDC_LINESTATE_READY             (CDC_LINESTATE_RTS | CDC_LINESTATE_DTR)
    4239
    43 struct ring_buffer
    44 {
     40struct ring_buffer {
    4541        uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
    4642        volatile uint32_t head;
    4743        volatile uint32_t tail;
     44        volatile bool full;
    4845};
    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;
     46ring_buffer cdc_rx_buffer = {{0}, 0, 0, false};
     47
     48typedef struct {
     49        uint32_t dwDTERate;
     50        uint8_t bCharFormat;
     51        uint8_t bParityType;
     52        uint8_t bDataBits;
     53        uint8_t lineState;
    5954} LineInfo;
    6055
    6156_Pragma("pack(1)")
    62 static volatile LineInfo _usbLineInfo = { 
    63    115200, // dWDTERate
    64     0x00,  // bCharFormat
    65     0x00,  // bParityType
    66     0x08,  // bDataBits
    67     0x00   // lineState
     57static volatile LineInfo _usbLineInfo = {
     58        115200, // dWDTERate
     59        0x00,   // bCharFormat
     60        0x00,   // bParityType
     61        0x08,   // bDataBits
     62        0x00    // lineState
    6863};
    6964
    70 static const CDCDescriptor _cdcInterface =
    71 {
    72 #if (defined CDC_ENABLED) && defined(HID_ENABLED)
     65static volatile int32_t breakValue = -1;
     66
     67static CDCDescriptor _cdcInterface = {
    7368        D_IAD(0, 2, CDC_COMMUNICATION_INTERFACE_CLASS, CDC_ABSTRACT_CONTROL_MODEL, 0),
    74 #endif
    75         //      CDC communication interface
    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 supported
    80         D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE),        // Communication interface is master, data interface is slave 0
    81         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         //      CDC data interface
    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)
    8883};
    8984_Pragma("pack()")
    9085
    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;
     86const void* _CDC_GetInterface(void)
     87{
     88        return &_cdcInterface;
     89}
     90
     91uint32_t _CDC_GetInterfaceLength(void)
     92{
     93        return sizeof(_cdcInterface);
     94}
     95
     96int CDC_GetInterface(uint8_t* interfaceNum)
     97{
     98        interfaceNum[0] += 2;   // uses 2
     99        return USBD_SendControl(&_cdcInterface,sizeof(_cdcInterface));
     100}
     101
     102bool CDC_Setup(Setup& pSetup)
     103{
     104        uint8_t requestType = pSetup.bmRequestType;
     105        uint8_t r = pSetup.bRequest;
    105106
    106107        if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
     
    108109                if (CDC_GET_LINE_CODING == r)
    109110                {
    110                         USBD_SendControl(0,(void*)&_usbLineInfo,7);
     111                        USBD_SendControl((void*)&_usbLineInfo, 7);
    111112                        return true;
    112113                }
     
    117118                if (CDC_SET_LINE_CODING == r)
    118119                {
    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);
    125121                }
    126122
    127123                if (CDC_SET_CONTROL_LINE_STATE == r)
    128124                {
    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                {
    130130                        // 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)
    133134                        {
    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                                 else
    138                                         cancelReset();
     135                                initiateReset(250);
     136                        }
     137                        else
     138                        {
     139                                cancelReset();
    139140                        }
    140141                        return false;
    141142                }
     143
     144                if (r == CDC_SEND_BREAK)
     145                {
     146                        breakValue = ((uint16_t)pSetup.wValueH << 8) | pSetup.wValueL;
     147                        return false;
     148                }
    142149        }
    143150        return false;
     
    159166void Serial_::accept(void)
    160167{
     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
     191int Serial_::available(void)
     192{
    161193        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
     203int Serial_::peek(void)
    183204{
    184205        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
     218int Serial_::read(void)
    189219{
    190220        ring_buffer *buffer = &cdc_rx_buffer;
    191221
    192         if (buffer->head == buffer->tail)
    193         {
    194                 return -1;
    195         }
    196         else
    197         {
    198                 return buffer->buffer[buffer->tail];
    199         }
    200 }
    201 
    202 int Serial_::read(void)
    203 {
    204         ring_buffer *buffer = &cdc_rx_buffer;
    205 
    206222        // 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)
    208229        {
    209230                return -1;
     
    213234                unsigned char c = buffer->buffer[buffer->tail];
    214235                buffer->tail = (uint32_t)(buffer->tail + 1) % CDC_SERIAL_BUFFER_SIZE;
    215                 if (USBD_Available(CDC_ENDPOINT_OUT))
    216                         accept();
     236                buffer->full = false;
    217237                return c;
    218238        }
     
    231251         bytes sent before the user opens the connection or after
    232252         the connection is closed are lost - just like with a UART. */
    233 
     253        if (_usbLineInfo.lineState > 0)  // Problem with Windows(R)
    234254        {
    235255                uint32_t r = USBD_Send(CDC_ENDPOINT_IN, buffer, size);
    236256
    237                 if (r > 0)
    238                 {
     257                if (r == 0) {
    239258                        return r;
    240                 } else
    241                 {
     259                } else {
    242260                        setWriteError();
    243261                        return 0;
    244262                }
    245         }
     263         }
    246264        setWriteError();
    247265        return 0;
     
    259277// We add a short delay before returning to fix a bug observed by Federico
    260278// where the port is configured (lineState != 0) but not quite opened.
    261 
    262279Serial_::operator bool()
    263280{
     
    277294}
    278295
    279 Serial_ SerialUSB;
     296int32_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
     316unsigned long Serial_::baud() {
     317        return _usbLineInfo.dwDTERate;
     318}
     319
     320uint8_t Serial_::stopbits() {
     321        return _usbLineInfo.bCharFormat;
     322}
     323
     324uint8_t Serial_::paritytype() {
     325        return _usbLineInfo.bParityType;
     326}
     327
     328uint8_t Serial_::numbits() {
     329        return _usbLineInfo.bDataBits;
     330}
     331
     332bool Serial_::dtr() {
     333        return _usbLineInfo.lineState & 0x1;
     334}
     335
     336bool Serial_::rts() {
     337        return _usbLineInfo.lineState & 0x2;
     338}
     339
     340Serial_ SerialUSB(USBDevice);
    280341
    281342#endif
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/HID.cpp

    r136 r224  
    2121#include "USBDesc.h"
    2222#include "sam.h"
    23 #include "USB/USB_device.h"
    2423
    2524
     
    4544//      HID report descriptor
    4645_Pragma("pack(1)")
    47 extern const uint8_t _hidReportDescriptor[] = {
     46extern const uint32_t _hidReportDescriptor[] = {
    4847        //      Mouse
    4948    0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)    // 54
     
    162161uint32_t WEAK HID_GetDescriptor(void)
    163162{
    164         return USBD_SendControl(0,_hidReportDescriptor,sizeof(_hidReportDescriptor));
     163        return USBD_SendControl(_hidReportDescriptor,sizeof(_hidReportDescriptor));
    165164}
    166165
     
    197196                if (HID_GET_IDLE == r)
    198197                {
    199                         UDD_Send(0, &_hid_idle, 1);
    200                         UDD_ClearIN();
     198                        USBD_Send(0, &_hid_idle, 1);
     199                        USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
    201200                        return true;
    202201                }
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBAPI.h

    r136 r224  
    11/*
    2   Copyright (c) 2012 Arduino.  All right reserved.
     2  Copyright (c) 2015 Arduino LLC.  All right reserved.
    33
    44  This library is free software; you can redistribute it and/or
     
    1616  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1717*/
    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
    3234
    3335#if defined __cplusplus
     
    3739
    3840//================================================================================
    39 //================================================================================
    40 //      USB
    41 
    42 class USBDevice_
    43 {
    44 public:
    45         USBDevice_();
     41// USB
     42//================================================================================
     43//================================================================================
     44// Low level API
     45typedef 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
     62class USBDevice_ {
     63public:
     64        USBDevice_() {};
     65
     66        // USB Device API
     67        void init();
     68        bool attach();  // Serial port goes down too...
     69        bool detach();
     70
    4671        bool configured();
    4772
    48         bool attach();
    49         bool detach();  // Serial port goes down too...
    50         void poll();
    51         void init();
    52 };
     73private:
     74        bool initialized;
     75};
     76
    5377extern USBDevice_ USBDevice;
    5478
    5579//================================================================================
    56 //================================================================================
    5780//      Serial over CDC (Serial1 is the physical port)
    5881
    5982class Serial_ : public Stream
    6083{
    61 private:
    62         RingBuffer *_cdc_rx_buffer;
    63 public:
     84public:
     85        Serial_(USBDevice_ &_usb) : usb(_usb) { }
    6486        void begin(uint32_t baud_count);
    6587        void begin(unsigned long, uint8_t);
     
    7597        using Print::write; // pull in write(str) from Print
    7698        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
     139private:
     140        USBDevice_ &usb;
     141        RingBuffer *_cdc_rx_buffer;
    77142};
    78143extern Serial_ SerialUSB;
     
    171236//================================================================================
    172237//================================================================================
    173 //      Low level API
    174 
    175 typedef struct
    176 {
    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 //================================================================================
    188238//      HID 'Driver'
    189239
     
    202252uint32_t                MSC_GetInterface(uint8_t* interfaceNum);
    203253uint32_t                MSC_GetDescriptor(uint32_t i);
    204 bool    MSC_Setup(Setup& setup);
     254bool    MSC_Setup(Setup& pSetup);
    205255bool    MSC_Data(uint8_t rx,uint8_t tx);
    206256
     
    209259//      CDC 'Driver'
    210260
    211 const void* CDC_GetInterface(/*uint8_t* interfaceNum*/);
    212 uint32_t WEAK CDC_GetInterfaceLength(void);
     261int CDC_GetInterface(uint8_t* interfaceNum);
     262const void* _CDC_GetInterface(void);
     263uint32_t _CDC_GetInterfaceLength(void);
    213264uint32_t                CDC_GetOtherInterface(uint8_t* interfaceNum);
    214265uint32_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);
     266bool    CDC_Setup(Setup& pSetup);
     267
     268
     269//================================================================================
     270//================================================================================
     271
     272uint32_t USBD_SendControl(const void* _data, uint32_t len);
    221273uint32_t USBD_RecvControl(void* d, uint32_t len);
     274void USBD_Calibrate();
    222275uint32_t USBD_SendInterfaces(void);
    223276bool USBD_ClassInterfaceRequest(Setup& setup);
     
    228281uint32_t USBD_Recv(uint32_t ep, void* data, uint32_t len);              // non-blocking
    229282uint32_t USBD_Recv(uint32_t ep);                                                        // non-blocking
     283uint8_t USBD_armRecv(uint32_t ep);
    230284void USBD_Flush(uint32_t ep);
    231285uint32_t USBD_Connected(void);
    232286
    233287#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 Barrett
    21/*
    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
    1517*/
     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"
    1626
    1727#include <stdlib.h>
    1828#include <stdio.h>
    1929#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
     32USBDevice_SAMD21G18x usbd;
    5633
    5734static char isRemoteWakeUpEnabled = 0;
    5835static char isEndpointHalt = 0;
     36
     37extern void (*gpf_isr)(void);
    5938
    6039
     
    6443};
    6544
     45#define USB_PID_ZERO_PRO        0x804d
     46#define USB_PRODUCT "Arduino M0 Pro"
    6647#ifndef USB_PRODUCT
    6748// Use a hardcoded product name if none is provided
     
    8869
    8970
    90 
    91 //      DEVICE DESCRIPTOR
    9271#if (defined CDC_ENABLED) && defined(HID_ENABLED)
    9372const DeviceDescriptor USB_DeviceDescriptor =
     
    10180#endif
    10281
     82
    10383//==================================================================
    10484
    10585volatile uint32_t _usbConfiguration = 0;
    106 volatile uint32_t _usbInitialized = 0;
    10786volatile uint32_t _usbSetInterface = 0;
    10887
     88static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
     89uint8_t udd_ep_out_cache_buffer[7][64];
     90
     91static __attribute__((__aligned__(4))) //__attribute__((__section__(".bss_hram0")))
     92uint8_t udd_ep_in_cache_buffer[7][64];
     93
    10994//==================================================================
    11095
    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)
     96bool _dry_run = false;
     97bool _pack_message = false;
     98uint16_t _pack_size = 0;
     99uint8_t _pack_buffer[256];
     100
     101
     102void 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
     114uint32_t USBD_Send(uint32_t ep, const void *data, uint32_t len)
     115{
     116        uint32_t length = 0;
     117
     118        if (!_usbConfiguration)
    123119                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        }
    146153        return len;
    147154}
    148155
    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;
     156uint32_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
     168uint32_t USBD_SendControl(const void* _data, uint32_t len)
     169{
     170        const uint8_t *data = reinterpret_cast<const uint8_t *>(_data);
    198171        uint32_t length = len;
    199172        uint32_t sent = 0;
    200173        uint32_t pos = 0;
    201174
    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        }
    211190
    212191        return length;
    213192}
    214193
    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];
     194bool USBD_SendStringDescriptor(const uint8_t *string, uint8_t maxlen)
     195{
     196        if (maxlen < 2)
     197                return false;
     198
     199        uint16_t buff[maxlen/2];
    221200        int l = 1;
    222201
    223         wLength -= 2;
    224         while (*string && wLength>0)
     202        maxlen -= 2;
     203        while (*string && maxlen>0)
    225204        {
    226205                buff[l++] = (uint8_t)(*string++);
    227                 wLength -= 2;
     206                maxlen -= 2;
    228207        }
    229208        buff[0] = (3<<8) | (l*2);
    230209
    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
     213uint8_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
     226uint32_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));
    255242                return true;
    256243        }
    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
    355252        return true;
    356253}
    357254
    358 static bool USBD_SendDescriptor(Setup* pSetup)
    359 {
    360         uint8_t t = pSetup->wValueH;
     255bool USBD_SendDescriptor(Setup &setup)
     256{
     257        uint8_t t = setup.wValueH;
    361258        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                }
    393278        }
    394279        else if (USB_STRING_DESCRIPTOR_TYPE == t)
    395280        {
    396                 TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");)
    397                 if (pSetup->wValueL == 0) {
     281                if (setup.wValueL == 0) {
    398282                        desc_addr = (const uint8_t*)&STRING_LANGUAGE;
    399283                }
    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);
    405289                }
    406290                else {
    407291                        return false;
    408292                }
    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) {
    420302                return false;
    421303        }
    422304
    423         if (desc_length == 0)
    424         {
     305        if (desc_length == 0) {
    425306                desc_length = *desc_addr;
    426307        }
    427308
    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);
    430310
    431311        return true;
    432312}
    433313
    434 
    435 void EndpointHandler(uint8_t bEndpoint)
    436 {
     314void 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
     367void sendZlp(uint32_t ep)
     368{
     369        // Set the byte count as zero
     370        usbd.epBank1SetByteCount(ep, 0);
     371}
     372
     373void 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
     389uint32_t EndPoints[] =
     390{
     391        USB_ENDPOINT_TYPE_CONTROL,
     392
    437393#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
     401void initEndpoints() {
     402        for (uint8_t i = 1; i < sizeof(EndPoints) && EndPoints[i] != 0; i++) {
     403                initEP(i, EndPoints[i]);
     404        }
     405}
     406
     407bool 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
     514bool 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
     531void 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
     540void 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
    443549                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
     568void 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))
    444621                {
    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                }
    476627       
    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)
    486638                {
    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))
    524642                        {
    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);
    652644                        }
    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
     654extern "C" void UDD_Handler(void) {
     655        ISRHandler();
     656}
    706657
    707658
    708659void USBD_Flush(uint32_t ep)
    709660{
    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
     671bool 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
     679uint8_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
     695uint32_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
     716uint32_t USBD_Available(uint32_t ep)
     717{
     718        return usbd.epBank0ByteCount(ep);
     719}
     720
     721uint8_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
     734uint32_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
     762uint32_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
     776void 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;
    731813}
    732814
    733815bool USBDevice_::attach()
    734816{
    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
    738824        _usbConfiguration = 0;
    739825        return true;
    740   }
    741   else
    742   {
    743     return false;
    744   }
    745 }
     826}
     827
    746828
    747829bool USBDevice_::detach()
    748830{
    749         if (_usbInitialized != 0UL)
    750         {
    751                 UDD_Detach();
    752                 return true;
    753         }
    754         else
    755         {
     831        if (!initialized)
    756832                return false;
    757         }
     833        usbd.detach();
     834        return true;
    758835}
    759836
    760837bool USBDevice_::configured()
    761838{
    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
     850USBDevice_ USBDevice;
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBCore.h

    r136 r224  
    1 // Copyright (c) 2010, Peter Barrett
    21/*
    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
    1517*/
     18/*
     19**Modified 04/04/2016 by Arduino.org development team
     20*/
     21
    1622
    1723#ifndef __USBCORE_H__
     
    3036#define SET_INTERFACE                           11
    3137
     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
    3250
    3351// bmRequestType
     
    4765#define REQUEST_RECIPIENT                       0x1F
    4866
    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)
    5170
    5271//      Class requests
     
    5574#define CDC_GET_LINE_CODING                     0x21
    5675#define CDC_SET_CONTROL_LINE_STATE      0x22
     76#define CDC_SEND_BREAK                          0x23
    5777
    5878#define MSC_RESET                                       0xFF
     
    108128#define MSC_SUBCLASS_SCSI                                               0x06
    109129#define MSC_PROTOCOL_BULK_ONLY                                  0x50
    110 
    111 #define HID_HID_DESCRIPTOR_TYPE                                 0x21
    112 #define HID_REPORT_DESCRIPTOR_TYPE                              0x22
    113 #define HID_PHYSICAL_DESCRIPTOR_TYPE                    0x23
    114 
    115 #define TX_RX_LED_PULSE_MS 100     //----- Tx & Rx led blinking during transmission (declaration)
    116130
    117131_Pragma("pack(1)")
     
    225239typedef struct
    226240{
    227 #if (defined CDC_ENABLED) && defined(HID_ENABLED)
    228241        //      IAD
    229242        IADDescriptor                           iad;    // Only needed on compound device
    230 #endif
    231243        //      Control
    232244        InterfaceDescriptor                     cif;
     
    249261        EndpointDescriptor                      out;
    250262} MSCDescriptor;
     263
    251264
    252265typedef struct
     
    273286
    274287#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
    275         { 18, 1, 0x110, _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 }
    276289/* Table 9-8. Standard Device Descriptor
    277290 * bLength, bDescriptorType, bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0,
     
    279292
    280293#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) }
    282295/* Table 9-10. Standard Configuration Descriptor
    283296 * bLength, bDescriptorType, wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration
    284297 * bmAttributes, bMaxPower */
    285  
     298
    286299#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
    287300        { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
     
    289302 * bLength, bDescriptorType, bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass,
    290303 * bInterfaceSubClass, bInterfaceProtocol, iInterface */
    291  
     304
    292305#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
    293306        { 7, 5, _addr,_attr,_packetSize, _interval }
     
    297310#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
    298311        { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
    299 /* iadclasscode_r10.pdf, Table 9–Z. Standard Interface Association Descriptor
     312/* iadclasscode_r10.pdf, Table 9\96Z. Standard Interface Association Descriptor
    300313 * bLength, bDescriptorType, bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction */
    301314#define D_HIDREPORT(_descriptorLength) \
     
    303316/* HID1_11.pdf  E.8 HID Descriptor (Mouse)
    304317 * bLength, bDescriptorType, bcdHID, bCountryCode, bNumDescriptors, bDescriptorType, wItemLength */
    305 
     318 
    306319// Functional Descriptor General Format
    307320#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 Barrett
    21/*
    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
    1520*/
    1621
     
    2227#define HID_ENABLED
    2328
     29
     30#ifdef CDC_ENABLED
     31#define CDC_INTERFACE_COUNT 2
     32#define CDC_ENPOINT_COUNT 3
     33#endif
     34
    2435// CDC
    2536#define CDC_ACM_INTERFACE       0       // CDC ACM
    2637#define CDC_DATA_INTERFACE      1       // CDC Data
     38#define CDC_FIRST_ENDPOINT  1
    2739#define CDC_ENDPOINT_ACM        1
    2840#define CDC_ENDPOINT_OUT        2
    2941#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
    3047
    3148// HID
     
    3350#define HID_ENDPOINT_INT        4 
    3451
     52
     53#define ISERIAL_MAX_LEN        20
     54
    3555// Defined string description
    3656#define IMANUFACTURER   1
    37 #define IPRODUCT                2
     57#define IPRODUCT    2
     58#define ISERIAL    3
    3859
    3960#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*/
    2921
    3022#ifndef USB_HOST_H_INCLUDED
     
    3224
    3325#include <stdint.h>
    34 
     26#include "samd21_host.h"
    3527#ifdef __cplusplus
    3628extern "C" {
    3729#endif
    3830
    39 #define tokSETUP                UOTGHS_HSTPIPCFG_PTOKEN_SETUP
    40 #define tokIN                   UOTGHS_HSTPIPCFG_PTOKEN_IN
    41 #define tokOUT                  UOTGHS_HSTPIPCFG_PTOKEN_OUT
    42 #define tokINHS                 UOTGHS_HSTPIPCFG_PTOKEN_IN
    43 #define tokOUTHS                UOTGHS_HSTPIPCFG_PTOKEN_OUT
     31#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
    4436
    4537//! \brief Device speed
     
    5850} uhd_vbus_state_t;
    5951
    60 //extern uhd_speed_t uhd_get_speed(void);
    61 
    62 extern void UHD_SetStack(void (*pf_isr)(void));
    6352extern void UHD_Init(void);
    64 extern void UHD_BusReset(void);
     53extern void UHD_Handler(void);
     54extern void USB_SetHandler(void (*pf_isr)(void));
    6555extern uhd_vbus_state_t UHD_GetVBUSState(void);
    6656extern uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size);
    6757extern 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);
     58extern void UHD_Pipe_CountZero(uint32_t ul_pipe);
    6859extern void UHD_Pipe_Free(uint32_t ul_pipe);
    6960extern 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
    2923
    3024#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
    3137
    3238#ifdef HOST_DEFINED
     
    3541#define TRACE_UOTGHS_HOST(x)
    3642
    37 //extern void (*gpf_isr)(void);
    38 
    3943// Handle UOTGHS Host driver state
    4044static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS;
    4145
    42  __attribute__((__aligned__(4))) UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];
     46__attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];
     47
     48extern void (*gpf_isr)(void);
    4349
    4450
    4551// NVM Software Calibration Area Mapping
    4652// USB TRANSN calibration value. Should be written to the USB PADCAL register.
    47 #define NVM_USB_PAD_TRANSN_POS  45
    48 #define NVM_USB_PAD_TRANSN_SIZE 5
     53#define NVM_USB_PAD_TRANSN_POS     45
     54#define NVM_USB_PAD_TRANSN_SIZE    5
    4955// USB TRANSP calibration value. Should be written to the USB PADCAL register.
    50 #define NVM_USB_PAD_TRANSP_POS  50
    51 #define NVM_USB_PAD_TRANSP_SIZE 5
     56#define NVM_USB_PAD_TRANSP_POS     50
     57#define NVM_USB_PAD_TRANSP_SIZE    5
    5258// 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
     62static void UHD_ISR(void);
    5563
    5664/**
     
    6068{
    6169        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);
    6476
    6577        /* Enable USB clock */
    6678        PM->APBBMASK.reg |= PM_APBBMASK_USB;
    6779
    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 );
    7583
    7684        /* ----------------------------------------------------------------------------------------------
    77          * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
    78          */
    79         GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) | // Generic Clock Multiplexer 6
    80                                         GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
    81                                         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 */
    8694        }
    8795
    8896        /* Reset */
    8997        USB->HOST.CTRLA.bit.SWRST = 1;
    90         while (USB->HOST.SYNCBUSY.bit.SWRST) {
     98        while (USB->HOST.SYNCBUSY.bit.SWRST)
     99        {
    91100                /* Sync wait */
    92101        }
    93102
    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);
    95107
    96108        /* 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        {
    103116                pad_transn = 5;
    104117        }
     
    106119        USB->HOST.PADCAL.bit.TRANSN = pad_transn;
    107120
    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        {
    114128                pad_transp = 29;
    115129        }
     
    117131        USB->HOST.PADCAL.bit.TRANSP = pad_transp;
    118132
    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        {
    125140                pad_trim = 3;
    126141        }
     
    128143        USB->HOST.PADCAL.bit.TRIM = pad_trim;
    129144
     145
    130146        /* Set the configuration */
    131         udd_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_FULL
    136         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        }
    140156
    141157        uhd_state = UHD_STATE_NO_VBUS;
    142158
     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
    143169        USB->HOST.CTRLB.bit.VBUSOK = 1;
    144170
    145171        // 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
     177static 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 */
    168184
    169185                /* get interrupt flags */
     
    171187
    172188                /* host SOF interrupt */
    173                 if (flags & USB_HOST_INTFLAG_HSOF) {
     189                if (flags & USB_HOST_INTFLAG_HSOF)
     190                {
    174191                        /* clear the flag */
    175192                        USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_HSOF;
    176                         uhd_state = UHD_STATE_CONNECTED;
     193                        uhd_state             = UHD_STATE_CONNECTED;
    177194                        return;
    178195                }
    179196
    180197                /* host reset interrupt */
    181                 if (flags & USB_HOST_INTFLAG_RST) {
     198                if (flags & USB_HOST_INTFLAG_RST)
     199                {
    182200                        /* clear the flag */
    183201                        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;
    185203                        return;
    186204                }
    187205
    188206                /* host upstream resume interrupts */
    189                 if (flags & USB_HOST_INTFLAG_UPRSM) {
     207                if (flags & USB_HOST_INTFLAG_UPRSM)
     208                {
    190209                        /* clear the flags */
    191210                        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;
    193212                        return;
    194213                }
    195214
    196215                /* host downstream resume interrupts */
    197                 if (flags & USB_HOST_INTFLAG_DNRSM) {
     216                if (flags & USB_HOST_INTFLAG_DNRSM)
     217                {
    198218                        /* clear the flags */
    199219                        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;
    201221                        return;
    202222                }
    203223
    204224                /* host wakeup interrupts */
    205                 if (flags & USB_HOST_INTFLAG_WAKEUP) {
     225                if (flags & USB_HOST_INTFLAG_WAKEUP)
     226                {
    206227                        /* clear the flags */
    207228                        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;
    209230                        return;
    210231                }
    211232
    212233                /* host ram access interrupt  */
    213                 if (flags & USB_HOST_INTFLAG_RAMACER) {
     234                if (flags & USB_HOST_INTFLAG_RAMACER)
     235                {
    214236                        /* clear the flag */
    215237                        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;
    217239                        return;
    218240                }
    219241
    220242                /* 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                                                        )
    223247                        /* clear the flag */
    224248                        uhd_ack_connection();
     
    231255                }
    232256
    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                                                        )
    236262                        /* clear the flag */
    237263                        uhd_ack_disconnection();
     
    246272                        return;
    247273                }
    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
    263281
    264282/**
     
    269287uhd_vbus_state_t UHD_GetVBUSState(void)
    270288{
    271         return uhd_state;
    272 }
    273 
     289   return uhd_state;
     290}
    274291
    275292
     
    283300 * \retval 1 error.
    284301 */
    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 }
     302uint32_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
    312318
    313319/**
     
    336342{
    337343        /* 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
    347362        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
     375void UHD_Pipe_CountZero(uint32_t ul_pipe)
     376{
     377        usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
     378}
    366379
    367380/**
     
    372385void UHD_Pipe_Free(uint32_t ul_pipe)
    373386{
    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
    382391
    383392/**
     
    390399 * \return number of data read.
    391400 */
    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 }
     401uint32_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
    413423
    414424/**
     
    419429 * \param data Buffer containing data to write.
    420430 */
    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;
     431void 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;
    437437}
    438438
     
    445445void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type)
    446446{
    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   
    450465        // 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)))
    453472
    454473/**
     
    463482uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type)
    464483{
    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*/
    2921
    3022#ifndef UOTGHS_HOST_H_INCLUDED
    3123#define UOTGHS_HOST_H_INCLUDED
    32 
    3324
    3425#ifdef __cplusplus
     
    3627#endif
    3728
    38 //! \ingroup usb_host_group
    39 //! \defgroup uhd_group USB Host Driver (UHD)
    40 //! UOTGHS low-level driver for USB host mode
    41 //!
    42 //! @{
     29extern __attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];
    4330
    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
    5133
    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
    6240
    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
    7042
    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)
    8146
    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
    9350
    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 
    9960
    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
    10762
    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
    11467
    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
    12671
    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;
    13074
    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
    13679
    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)
    14382
    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)
    15888
    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
    16492
    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)
    17197
    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
    182100
    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)
    190111
     112// Endpoint Interrupt Summary
     113#define uhd_endpoint_interrupt()            USB->HOST.PINTSMRY.reg
    191114
    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
    194119
    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
    204124
    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
    394127
    395128#ifdef __cplusplus
Note: See TracChangeset for help on using the changeset viewer.