local fork (temporary)
Dependents: VodafoneUSBModem_bleedingedge2
Fork of USBHostWANDongle_bleedingedge by
USBHost/USBEndpoint.cpp@27:4de37cd81412, 2013-04-26 (annotated)
- Committer:
- ashleymills
- Date:
- Fri Apr 26 16:52:02 2013 +0000
- Revision:
- 27:4de37cd81412
- Parent:
- 12:a712bad7a979
Some dead code removed.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
donatien | 9:c9e9817c398c | 1 | /* Copyright (c) 2010-2012 mbed.org, MIT License |
donatien | 0:ae46a0638b2c | 2 | * |
donatien | 0:ae46a0638b2c | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
donatien | 0:ae46a0638b2c | 4 | * and associated documentation files (the "Software"), to deal in the Software without |
donatien | 0:ae46a0638b2c | 5 | * restriction, including without limitation the rights to use, copy, modify, merge, publish, |
donatien | 0:ae46a0638b2c | 6 | * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the |
donatien | 0:ae46a0638b2c | 7 | * Software is furnished to do so, subject to the following conditions: |
donatien | 0:ae46a0638b2c | 8 | * |
donatien | 0:ae46a0638b2c | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
donatien | 0:ae46a0638b2c | 10 | * substantial portions of the Software. |
donatien | 0:ae46a0638b2c | 11 | * |
donatien | 0:ae46a0638b2c | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
donatien | 0:ae46a0638b2c | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
donatien | 0:ae46a0638b2c | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
donatien | 0:ae46a0638b2c | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
donatien | 0:ae46a0638b2c | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
donatien | 0:ae46a0638b2c | 17 | */ |
donatien | 0:ae46a0638b2c | 18 | |
donatien | 0:ae46a0638b2c | 19 | |
donatien | 0:ae46a0638b2c | 20 | #define __DEBUG__ 0 //Maximum verbosity |
donatien | 0:ae46a0638b2c | 21 | #ifndef __MODULE__ |
donatien | 9:c9e9817c398c | 22 | #define __MODULE__ "USBEndpoint.cpp" |
donatien | 0:ae46a0638b2c | 23 | #endif |
donatien | 0:ae46a0638b2c | 24 | |
donatien | 12:a712bad7a979 | 25 | #include "core/dbg.h" |
donatien | 0:ae46a0638b2c | 26 | #include <cstdint> |
ashleymills | 27:4de37cd81412 | 27 | #include "capi/error.h" |
donatien | 0:ae46a0638b2c | 28 | |
donatien | 9:c9e9817c398c | 29 | #include "USBEndpoint.h" |
donatien | 0:ae46a0638b2c | 30 | |
donatien | 0:ae46a0638b2c | 31 | |
donatien | 9:c9e9817c398c | 32 | void USBEndpoint::init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]) { |
donatien | 0:ae46a0638b2c | 33 | this->hced = hced; |
donatien | 0:ae46a0638b2c | 34 | this->type = type; |
donatien | 0:ae46a0638b2c | 35 | this->dir = /*(type == CONTROL_ENDPOINT) ? OUT :*/ dir; |
donatien | 0:ae46a0638b2c | 36 | setup = (type == CONTROL_ENDPOINT) ? true : false; |
donatien | 0:ae46a0638b2c | 37 | |
donatien | 0:ae46a0638b2c | 38 | //TDs have been allocated by the host |
donatien | 0:ae46a0638b2c | 39 | memcpy((HCTD**)this->td_list, td_list, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define |
donatien | 0:ae46a0638b2c | 40 | memcpy(td_list[0], 0, sizeof(HCTD)); |
donatien | 0:ae46a0638b2c | 41 | memcpy(td_list[1], 0, sizeof(HCTD)); |
donatien | 0:ae46a0638b2c | 42 | |
donatien | 0:ae46a0638b2c | 43 | this->hced->control = 0; |
donatien | 0:ae46a0638b2c | 44 | //Empty queue |
donatien | 0:ae46a0638b2c | 45 | this->hced->tailTD = (uint32_t)td_list[0]; |
donatien | 0:ae46a0638b2c | 46 | this->hced->headTD = (uint32_t)td_list[0]; |
donatien | 0:ae46a0638b2c | 47 | this->hced->nextED = 0; |
donatien | 0:ae46a0638b2c | 48 | |
donatien | 0:ae46a0638b2c | 49 | this->hced->control = ((ep_number & 0x7F) << 7) // Endpoint address |
donatien | 0:ae46a0638b2c | 50 | | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 ) // direction : Out = 1, 2 = In |
donatien | 0:ae46a0638b2c | 51 | | ((size & 0x3ff) << 16); // MaxPkt Size |
donatien | 0:ae46a0638b2c | 52 | |
donatien | 0:ae46a0638b2c | 53 | //carry = false; |
donatien | 0:ae46a0638b2c | 54 | transfer_len = 0; |
donatien | 0:ae46a0638b2c | 55 | transferred = 0; |
donatien | 0:ae46a0638b2c | 56 | buf_start = 0; |
donatien | 0:ae46a0638b2c | 57 | nextEp = NULL; |
donatien | 0:ae46a0638b2c | 58 | |
donatien | 0:ae46a0638b2c | 59 | td_current = td_list[0]; |
donatien | 0:ae46a0638b2c | 60 | td_next = td_list[1]; |
donatien | 0:ae46a0638b2c | 61 | |
donatien | 0:ae46a0638b2c | 62 | state = USB_TYPE_IDLE; |
donatien | 0:ae46a0638b2c | 63 | } |
donatien | 0:ae46a0638b2c | 64 | |
donatien | 9:c9e9817c398c | 65 | void USBEndpoint::setSize(uint32_t size) { |
donatien | 0:ae46a0638b2c | 66 | hced->control &= ~(0x3ff << 16); |
donatien | 0:ae46a0638b2c | 67 | hced->control |= (size << 16); |
donatien | 0:ae46a0638b2c | 68 | } |
donatien | 0:ae46a0638b2c | 69 | |
donatien | 0:ae46a0638b2c | 70 | |
donatien | 9:c9e9817c398c | 71 | uint32_t USBEndpoint::getSize() { |
donatien | 0:ae46a0638b2c | 72 | return (hced->control >> 16) & 0x3ff; |
donatien | 0:ae46a0638b2c | 73 | } |
donatien | 0:ae46a0638b2c | 74 | |
donatien | 9:c9e9817c398c | 75 | void USBEndpoint::setDeviceAddress(uint8_t addr) { |
donatien | 0:ae46a0638b2c | 76 | hced->control &= ~(0x7f); |
donatien | 0:ae46a0638b2c | 77 | hced->control |= (addr & 0x7F); |
donatien | 0:ae46a0638b2c | 78 | } |
donatien | 0:ae46a0638b2c | 79 | |
donatien | 9:c9e9817c398c | 80 | uint8_t USBEndpoint::getDeviceAddress() { |
donatien | 0:ae46a0638b2c | 81 | return hced->control & 0x7f; |
donatien | 0:ae46a0638b2c | 82 | } |
donatien | 0:ae46a0638b2c | 83 | |
donatien | 9:c9e9817c398c | 84 | void USBEndpoint::setSpeed(uint8_t speed) { |
donatien | 0:ae46a0638b2c | 85 | if(speed) { |
donatien | 0:ae46a0638b2c | 86 | DBG("SET LOW SPEED"); |
donatien | 0:ae46a0638b2c | 87 | } |
donatien | 0:ae46a0638b2c | 88 | hced->control &= ~(1 << 13); |
donatien | 0:ae46a0638b2c | 89 | hced->control |= (speed << 13); |
donatien | 0:ae46a0638b2c | 90 | } |
donatien | 0:ae46a0638b2c | 91 | |
donatien | 0:ae46a0638b2c | 92 | |
donatien | 9:c9e9817c398c | 93 | void USBEndpoint::setNextToken(uint32_t token) { //Only for control Eps |
donatien | 0:ae46a0638b2c | 94 | switch (token) { |
donatien | 0:ae46a0638b2c | 95 | case TD_SETUP: |
donatien | 0:ae46a0638b2c | 96 | dir = OUT; |
donatien | 0:ae46a0638b2c | 97 | setup = true; |
donatien | 0:ae46a0638b2c | 98 | break; |
donatien | 0:ae46a0638b2c | 99 | case TD_IN: |
donatien | 0:ae46a0638b2c | 100 | dir = IN; |
donatien | 0:ae46a0638b2c | 101 | setup = false; |
donatien | 0:ae46a0638b2c | 102 | break; |
donatien | 0:ae46a0638b2c | 103 | case TD_OUT: |
donatien | 0:ae46a0638b2c | 104 | dir = OUT; |
donatien | 0:ae46a0638b2c | 105 | setup = false; |
donatien | 0:ae46a0638b2c | 106 | break; |
donatien | 0:ae46a0638b2c | 107 | } |
donatien | 0:ae46a0638b2c | 108 | } |
donatien | 0:ae46a0638b2c | 109 | |
donatien | 9:c9e9817c398c | 110 | volatile HCTD* USBEndpoint::getNextTD() |
donatien | 0:ae46a0638b2c | 111 | { |
donatien | 0:ae46a0638b2c | 112 | return td_current/*(HCTD*) hced->tailTD*/; //It's the tailing one |
donatien | 0:ae46a0638b2c | 113 | } |
donatien | 0:ae46a0638b2c | 114 | |
donatien | 9:c9e9817c398c | 115 | void USBEndpoint::queueTransfer() { |
donatien | 0:ae46a0638b2c | 116 | //Try with OHCI impl |
donatien | 0:ae46a0638b2c | 117 | //Caller of getNextTD() has now populated the td |
donatien | 0:ae46a0638b2c | 118 | //So insert it into queue |
donatien | 0:ae46a0638b2c | 119 | |
donatien | 0:ae46a0638b2c | 120 | //Find an OTHER free td |
donatien | 0:ae46a0638b2c | 121 | //TODO: if we had more than 2 tds, this would have to be changed |
donatien | 0:ae46a0638b2c | 122 | /*HCTD* toSendTD = (HCTD*) hced->tailTD;*/ |
donatien | 0:ae46a0638b2c | 123 | //HCTD* freeTD; |
donatien | 0:ae46a0638b2c | 124 | /* |
donatien | 0:ae46a0638b2c | 125 | if( hced->tailTD == td_list[0] ) |
donatien | 0:ae46a0638b2c | 126 | { |
donatien | 0:ae46a0638b2c | 127 | freeTD = td_list[1]; |
donatien | 0:ae46a0638b2c | 128 | } |
donatien | 0:ae46a0638b2c | 129 | else *//*if( hced->tailTD == (uint32_t) td_list[1] )*/ |
donatien | 0:ae46a0638b2c | 130 | /*{ |
donatien | 0:ae46a0638b2c | 131 | freeTD = td_list[0]; |
donatien | 0:ae46a0638b2c | 132 | } |
donatien | 0:ae46a0638b2c | 133 | */ |
donatien | 0:ae46a0638b2c | 134 | |
donatien | 0:ae46a0638b2c | 135 | /* |
donatien | 0:ae46a0638b2c | 136 | freeTD->control = 0; |
donatien | 0:ae46a0638b2c | 137 | freeTD->currBufPtr = 0; |
donatien | 0:ae46a0638b2c | 138 | freeTD->bufEnd = 0; |
donatien | 0:ae46a0638b2c | 139 | freeTD->nextTD = 0; |
donatien | 0:ae46a0638b2c | 140 | |
donatien | 0:ae46a0638b2c | 141 | td_current = toSendTD; |
donatien | 0:ae46a0638b2c | 142 | */ |
donatien | 0:ae46a0638b2c | 143 | transfer_len = td_current->bufEnd - td_current->currBufPtr + 1; |
donatien | 0:ae46a0638b2c | 144 | transferred = transfer_len; |
donatien | 0:ae46a0638b2c | 145 | buf_start = td_current->currBufPtr; |
donatien | 0:ae46a0638b2c | 146 | |
donatien | 0:ae46a0638b2c | 147 | //No add this free TD at this end of the queue |
donatien | 0:ae46a0638b2c | 148 | state = USB_TYPE_PROCESSING; |
donatien | 0:ae46a0638b2c | 149 | td_current->nextTD = (volatile uint32_t)td_next; |
donatien | 0:ae46a0638b2c | 150 | hced->tailTD = (volatile uint32_t)td_next; |
donatien | 0:ae46a0638b2c | 151 | |
donatien | 0:ae46a0638b2c | 152 | #if 0 |
donatien | 0:ae46a0638b2c | 153 | // if TD list empty -> we put the head of the list |
donatien | 0:ae46a0638b2c | 154 | if (!hced->headTD) { |
donatien | 0:ae46a0638b2c | 155 | state = USB_TYPE_IDLE; |
donatien | 0:ae46a0638b2c | 156 | hced->headTD = (uint32_t)(td); |
donatien | 0:ae46a0638b2c | 157 | hced->tailTD = (uint32_t)(td); |
donatien | 0:ae46a0638b2c | 158 | tailTD = (HCTD *) (hced->headTD); |
donatien | 0:ae46a0638b2c | 159 | //DBG("queue null transfer: endpoint: %p, %08X\r\n", this, (uint32_t)(td)); |
donatien | 0:ae46a0638b2c | 160 | } else { |
donatien | 0:ae46a0638b2c | 161 | state = USB_TYPE_PROCESSING; |
donatien | 0:ae46a0638b2c | 162 | td->nextTD = (uint32_t)headTD & ~(0x0f); |
donatien | 0:ae46a0638b2c | 163 | hced->headTD = (uint32_t)(td) | ((carry) ? 0x2 : 0); |
donatien | 0:ae46a0638b2c | 164 | } |
donatien | 0:ae46a0638b2c | 165 | headTD = (HCTD *) ((hced->headTD) & ~(0x3)); |
donatien | 0:ae46a0638b2c | 166 | transfer_len = td->bufEnd - td->currBufPtr + 1; |
donatien | 0:ae46a0638b2c | 167 | transferred = transfer_len; |
donatien | 0:ae46a0638b2c | 168 | buf_start = td->currBufPtr; |
donatien | 0:ae46a0638b2c | 169 | #endif |
donatien | 0:ae46a0638b2c | 170 | //printf("queue real transfer: endpoint: %p \t headTD: %p \t head: %08X \t tail: %08X \t td: %08X \t nexttd: %08X\r\n", this, hced->headTD, hced->headTD, ((HCTD *)((hced->headTD) & ~(0x0f)))->nextTD, toSendTD, toSendTD->nextTD); |
donatien | 0:ae46a0638b2c | 171 | } |
donatien | 0:ae46a0638b2c | 172 | |
donatien | 9:c9e9817c398c | 173 | volatile HCTD * USBEndpoint::getProcessedTD() |
donatien | 0:ae46a0638b2c | 174 | { |
donatien | 0:ae46a0638b2c | 175 | return td_current; |
donatien | 0:ae46a0638b2c | 176 | } |
donatien | 0:ae46a0638b2c | 177 | |
donatien | 9:c9e9817c398c | 178 | void USBEndpoint::setLengthTransferred(int len) { |
donatien | 0:ae46a0638b2c | 179 | transferred = len; |
donatien | 0:ae46a0638b2c | 180 | } |
donatien | 0:ae46a0638b2c | 181 | |
donatien | 9:c9e9817c398c | 182 | uint32_t USBEndpoint::getBufStart() { |
donatien | 0:ae46a0638b2c | 183 | return buf_start; |
donatien | 0:ae46a0638b2c | 184 | } |
donatien | 0:ae46a0638b2c | 185 | |
donatien | 9:c9e9817c398c | 186 | void USBEndpoint::unqueueTransfer(volatile HCTD * td) { |
donatien | 0:ae46a0638b2c | 187 | //printf("unqueue transfer: %p on endpoint: %p\r\n", (void *)td, this); |
donatien | 0:ae46a0638b2c | 188 | //headTD = tailTD; //FIXME FIXME |
donatien | 0:ae46a0638b2c | 189 | // hced->headTD = hced->headTD | (td-> & 0x02); |
donatien | 0:ae46a0638b2c | 190 | if(td != td_current) |
donatien | 0:ae46a0638b2c | 191 | { |
donatien | 0:ae46a0638b2c | 192 | ERR("MISMATCH"); |
donatien | 0:ae46a0638b2c | 193 | ERR("this=%p, td_current = %p, td_next=%p, td=%p", this, td_current, td_next, td); |
donatien | 0:ae46a0638b2c | 194 | error(""); |
donatien | 0:ae46a0638b2c | 195 | } |
donatien | 0:ae46a0638b2c | 196 | td->control=0; |
donatien | 0:ae46a0638b2c | 197 | td->currBufPtr=0; |
donatien | 0:ae46a0638b2c | 198 | td->bufEnd=0; |
donatien | 0:ae46a0638b2c | 199 | td->nextTD=0; |
donatien | 0:ae46a0638b2c | 200 | hced->headTD = hced->tailTD | (hced->headTD & 0x2); //Carry bit |
donatien | 0:ae46a0638b2c | 201 | td_current = td_next; |
donatien | 0:ae46a0638b2c | 202 | td_next = td; |
donatien | 0:ae46a0638b2c | 203 | DBG("current:%p, next:%p", td_current, td_next); |
donatien | 0:ae46a0638b2c | 204 | } |
donatien | 0:ae46a0638b2c | 205 | |
donatien | 9:c9e9817c398c | 206 | ENDPOINT_TYPE USBEndpoint::getType() { |
donatien | 0:ae46a0638b2c | 207 | return type; |
donatien | 0:ae46a0638b2c | 208 | } |
donatien | 0:ae46a0638b2c | 209 | |
donatien | 0:ae46a0638b2c | 210 | |
donatien | 9:c9e9817c398c | 211 | USBEndpoint * USBEndpoint::nextEndpoint() { |
donatien | 9:c9e9817c398c | 212 | return (USBEndpoint*)nextEp; |
donatien | 0:ae46a0638b2c | 213 | } |
donatien | 0:ae46a0638b2c | 214 | |
donatien | 0:ae46a0638b2c | 215 | |
donatien | 9:c9e9817c398c | 216 | void USBEndpoint::queueEndpoint(USBEndpoint * ed) { |
donatien | 0:ae46a0638b2c | 217 | nextEp = ed; |
donatien | 0:ae46a0638b2c | 218 | hced->nextED = (ed == NULL) ? 0 : (uint32_t)ed->getHCED(); |
donatien | 0:ae46a0638b2c | 219 | } |
donatien | 0:ae46a0638b2c | 220 | |
donatien | 9:c9e9817c398c | 221 | volatile HCED * USBEndpoint::getHCED() { |
donatien | 0:ae46a0638b2c | 222 | return hced; |
donatien | 0:ae46a0638b2c | 223 | } |
donatien | 0:ae46a0638b2c | 224 | |
donatien | 0:ae46a0638b2c | 225 | |
donatien | 9:c9e9817c398c | 226 | volatile HCTD * USBEndpoint::getHeadTD() { |
donatien | 0:ae46a0638b2c | 227 | //return headTD; |
donatien | 0:ae46a0638b2c | 228 | return (volatile HCTD*) (hced->headTD & ~0xF); |
donatien | 0:ae46a0638b2c | 229 | } |
donatien | 7:c4483d48fe96 | 230 | |
donatien | 9:c9e9817c398c | 231 | volatile HCTD ** USBEndpoint::getTDList() |
donatien | 7:c4483d48fe96 | 232 | { |
donatien | 7:c4483d48fe96 | 233 | return td_list; |
donatien | 7:c4483d48fe96 | 234 | } |