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

1.7.10のファイルに更新

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/USBCore.cpp

    r136 r224  
    1 // Copyright (c) 2010, Peter 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;
Note: See TracChangeset for help on using the changeset viewer.