USBHost library

Dependencies:   FATFileSystem

Dependents:   Project RoboticsCatAndMouse_HumanDriver RoboticsCatAndMouse_AutonomousDriver

Fork of USBHost by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBEndpoint.cpp Source File

USBEndpoint.cpp

00001 /* mbed USBHost Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include "dbg.h"
00019 #include "USBEndpoint.h"
00020 
00021 void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
00022 {
00023     hced = hced_;
00024     type = type_;
00025     dir = dir_;
00026     setup = (type == CONTROL_ENDPOINT) ? true : false;
00027 
00028     //TDs have been allocated by the host
00029     memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
00030     memset(td_list_[0], 0, sizeof(HCTD));
00031     memset(td_list_[1], 0, sizeof(HCTD));
00032     
00033     td_list[0]->ep = this;
00034     td_list[1]->ep = this;
00035 
00036     hced->control = 0;
00037     //Empty queue
00038     hced->tailTD = td_list[0];
00039     hced->headTD = td_list[0];
00040     hced->nextED = 0;
00041 
00042     address = (ep_number & 0x7F) | ((dir - 1) << 7);
00043 
00044     hced->control = ((ep_number & 0x7F) << 7)                         // Endpoint address
00045                     | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 )  // direction : Out = 1, 2 = In
00046                     | ((size & 0x3ff) << 16);                         // MaxPkt Size
00047 
00048     transfer_len = 0;
00049     transferred = 0;
00050     buf_start = 0;
00051     nextEp = NULL;
00052 
00053     td_current = td_list[0];
00054     td_next = td_list[1];
00055     
00056     intf_nb = 0;
00057 
00058     state = USB_TYPE_IDLE;
00059 }
00060 
00061 void USBEndpoint::setSize(uint32_t size)
00062 {
00063     hced->control &= ~(0x3ff << 16);
00064     hced->control |= (size << 16);
00065 }
00066 
00067 
00068 void USBEndpoint::setDeviceAddress(uint8_t addr)
00069 {
00070     hced->control &= ~(0x7f);
00071     hced->control |= (addr & 0x7F);
00072 }
00073 
00074 void USBEndpoint::setSpeed(uint8_t speed)
00075 {
00076     hced->control &= ~(1 << 13);
00077     hced->control |= (speed << 13);
00078 }
00079 
00080 //Only for control Eps
00081 void USBEndpoint::setNextToken(uint32_t token)
00082 {
00083     switch (token) {
00084         case TD_SETUP:
00085             dir = OUT;
00086             setup = true;
00087             break;
00088         case TD_IN:
00089             dir = IN;
00090             setup = false;
00091             break;
00092         case TD_OUT:
00093             dir = OUT;
00094             setup = false;
00095             break;
00096     }
00097 }
00098 
00099 struct {
00100     USB_TYPE type;
00101     const char * str;
00102 } static type_string[] = {
00103 /*0*/   {USB_TYPE_OK, "USB_TYPE_OK"},
00104         {USB_TYPE_CRC_ERROR, "USB_TYPE_CRC_ERROR"},
00105         {USB_TYPE_BIT_STUFFING_ERROR, "USB_TYPE_BIT_STUFFING_ERROR"},
00106         {USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR, "USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR"},
00107         {USB_TYPE_STALL_ERROR, "USB_TYPE_STALL_ERROR"},
00108 /*5*/   {USB_TYPE_DEVICE_NOT_RESPONDING_ERROR, "USB_TYPE_DEVICE_NOT_RESPONDING_ERROR"},
00109         {USB_TYPE_PID_CHECK_FAILURE_ERROR, "USB_TYPE_PID_CHECK_FAILURE_ERROR"},
00110         {USB_TYPE_UNEXPECTED_PID_ERROR, "USB_TYPE_UNEXPECTED_PID_ERROR"},
00111         {USB_TYPE_DATA_OVERRUN_ERROR, "USB_TYPE_DATA_OVERRUN_ERROR"},
00112         {USB_TYPE_DATA_UNDERRUN_ERROR, "USB_TYPE_DATA_UNDERRUN_ERROR"},
00113 /*10*/  {USB_TYPE_ERROR, "USB_TYPE_ERROR"},
00114         {USB_TYPE_ERROR, "USB_TYPE_ERROR"},
00115         {USB_TYPE_BUFFER_OVERRUN_ERROR, "USB_TYPE_BUFFER_OVERRUN_ERROR"},
00116         {USB_TYPE_BUFFER_UNDERRUN_ERROR, "USB_TYPE_BUFFER_UNDERRUN_ERROR"},
00117         {USB_TYPE_DISCONNECTED, "USB_TYPE_DISCONNECTED"},
00118 /*15*/  {USB_TYPE_FREE, "USB_TYPE_FREE"},
00119         {USB_TYPE_IDLE, "USB_TYPE_IDLE"},
00120         {USB_TYPE_PROCESSING, "USB_TYPE_PROCESSING"},
00121         {USB_TYPE_ERROR, "USB_TYPE_ERROR"}
00122 };
00123 
00124 void USBEndpoint::setState(uint8_t st) {
00125     if (st > 18)
00126         return;
00127     state = type_string[st].type;
00128 }
00129 
00130 
00131 const char * USBEndpoint::getStateString() {
00132     return type_string[state].str;
00133 }
00134 
00135 void USBEndpoint::queueTransfer()
00136 {
00137     transfer_len = (uint32_t)td_current->bufEnd - (uint32_t)td_current->currBufPtr + 1;
00138     transferred = transfer_len;
00139     buf_start = (uint8_t *)td_current->currBufPtr;
00140 
00141     //Now add this free TD at this end of the queue
00142     state = USB_TYPE_PROCESSING;
00143     td_current->nextTD = td_next;
00144     hced->tailTD = td_next;
00145 }
00146 
00147 void USBEndpoint::unqueueTransfer(volatile HCTD * td)
00148 {
00149     td->control=0;
00150     td->currBufPtr=0;
00151     td->bufEnd=0;
00152     td->nextTD=0;
00153     hced->headTD = (HCTD *)((uint32_t)hced->tailTD | ((uint32_t)hced->headTD & 0x2)); //Carry bit
00154     td_current = td_next;
00155     td_next = td;
00156 }
00157 
00158 void USBEndpoint::queueEndpoint(USBEndpoint * ed)
00159 {
00160     nextEp = ed;
00161     hced->nextED = (ed == NULL) ? 0 : ed->getHCED();
00162 }