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/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
Note: See TracChangeset for help on using the changeset viewer.