First step: AutoIP compiled in and working

Dependencies:   mbed

Committer:
darran
Date:
Fri Jun 18 15:54:21 2010 +0000
Revision:
1:4218cacaf696
Parent:
0:55a05330f8cc

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
darran 0:55a05330f8cc 1
darran 0:55a05330f8cc 2 /*
darran 0:55a05330f8cc 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
darran 0:55a05330f8cc 4
darran 0:55a05330f8cc 5 Permission is hereby granted, free of charge, to any person obtaining a copy
darran 0:55a05330f8cc 6 of this software and associated documentation files (the "Software"), to deal
darran 0:55a05330f8cc 7 in the Software without restriction, including without limitation the rights
darran 0:55a05330f8cc 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
darran 0:55a05330f8cc 9 copies of the Software, and to permit persons to whom the Software is
darran 0:55a05330f8cc 10 furnished to do so, subject to the following conditions:
darran 0:55a05330f8cc 11
darran 0:55a05330f8cc 12 The above copyright notice and this permission notice shall be included in
darran 0:55a05330f8cc 13 all copies or substantial portions of the Software.
darran 0:55a05330f8cc 14
darran 0:55a05330f8cc 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
darran 0:55a05330f8cc 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
darran 0:55a05330f8cc 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
darran 0:55a05330f8cc 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
darran 0:55a05330f8cc 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
darran 0:55a05330f8cc 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
darran 0:55a05330f8cc 21 THE SOFTWARE.
darran 0:55a05330f8cc 22 */
darran 0:55a05330f8cc 23
darran 0:55a05330f8cc 24 #include "UsbEndpoint.h"
darran 0:55a05330f8cc 25
darran 0:55a05330f8cc 26 #include "netCfg.h"
darran 0:55a05330f8cc 27 #if NET_USB
darran 0:55a05330f8cc 28
darran 0:55a05330f8cc 29 EdPool::EdPool(int size) : m_pos(0)
darran 0:55a05330f8cc 30 {
darran 0:55a05330f8cc 31 m_pool = new uint8_t[2*size*0x10];
darran 0:55a05330f8cc 32 printf("\r\n--HCED* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10);
darran 0:55a05330f8cc 33 }
darran 0:55a05330f8cc 34
darran 0:55a05330f8cc 35 EdPool::~EdPool()
darran 0:55a05330f8cc 36 {
darran 0:55a05330f8cc 37 printf("\r\n--~EdPool()--\r\n");
darran 0:55a05330f8cc 38 delete[] m_pool;
darran 0:55a05330f8cc 39 }
darran 0:55a05330f8cc 40
darran 0:55a05330f8cc 41 HCED* EdPool::get()
darran 0:55a05330f8cc 42 {
darran 0:55a05330f8cc 43 printf("\r\n--HCED* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]);
darran 0:55a05330f8cc 44 while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 )
darran 0:55a05330f8cc 45 {
darran 0:55a05330f8cc 46 m_pos++;
darran 0:55a05330f8cc 47 }
darran 0:55a05330f8cc 48 HCED* pEd = (HCED*) &m_pool[m_pos];
darran 0:55a05330f8cc 49 m_pos += sizeof(HCED);
darran 0:55a05330f8cc 50 printf("\r\n--HCED* pEd = %p--\r\n", pEd);
darran 0:55a05330f8cc 51 return pEd;
darran 0:55a05330f8cc 52 }
darran 0:55a05330f8cc 53
darran 0:55a05330f8cc 54 TdPool::TdPool(int size) : m_pos(0)
darran 0:55a05330f8cc 55 {
darran 0:55a05330f8cc 56 m_pool = new uint8_t[2*size*0x10];
darran 0:55a05330f8cc 57 printf("\r\n--HCTD* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10);
darran 0:55a05330f8cc 58 }
darran 0:55a05330f8cc 59
darran 0:55a05330f8cc 60 TdPool::~TdPool()
darran 0:55a05330f8cc 61 {
darran 0:55a05330f8cc 62 printf("\r\n--~EdPool()--\r\n");
darran 0:55a05330f8cc 63 delete[] m_pool;
darran 0:55a05330f8cc 64 }
darran 0:55a05330f8cc 65
darran 0:55a05330f8cc 66 HCTD* TdPool::get()
darran 0:55a05330f8cc 67 {
darran 0:55a05330f8cc 68 printf("\r\n--HCTD* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]);
darran 0:55a05330f8cc 69 while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 )
darran 0:55a05330f8cc 70 {
darran 0:55a05330f8cc 71 m_pos++;
darran 0:55a05330f8cc 72 }
darran 0:55a05330f8cc 73 HCTD* pTd = (HCTD*) &m_pool[m_pos];
darran 0:55a05330f8cc 74 m_pos += sizeof(HCTD);
darran 0:55a05330f8cc 75 printf("\r\n--HCTD* pTd = %p--\r\n", pTd);
darran 0:55a05330f8cc 76 return pTd;
darran 0:55a05330f8cc 77 }
darran 0:55a05330f8cc 78 //uint8_t TdPool::pool[16*0x10]={0};//Ok for 2 Eps (2*(2Tds/Ep*2Eps))
darran 0:55a05330f8cc 79 //int TdPool::pos = 0;
darran 0:55a05330f8cc 80
darran 0:55a05330f8cc 81 extern volatile HCED* EDBulkHead;
darran 0:55a05330f8cc 82 //volatile HCED* UsbEndpoint::m_pNextEd = NULL;
darran 0:55a05330f8cc 83
darran 0:55a05330f8cc 84 UsbEndpoint::UsbEndpoint( /* UsbDevice*, */ uint8_t ep, bool dir, uint16_t size ) : m_edPool(1), m_tdPool(2), m_done(true), m_len(0), m_pBufStartPtr(NULL)
darran 0:55a05330f8cc 85 {
darran 0:55a05330f8cc 86 #if 1
darran 0:55a05330f8cc 87
darran 0:55a05330f8cc 88 m_pEd = m_edPool.get();
darran 0:55a05330f8cc 89
darran 0:55a05330f8cc 90 #else
darran 0:55a05330f8cc 91 if(m_pNextEd == NULL)
darran 0:55a05330f8cc 92 {
darran 0:55a05330f8cc 93 m_pNextEd = EDBulkHead;
darran 0:55a05330f8cc 94 //printf("\r\n--m_pEd = %p < EDBulkHead = %p --\r\n", m_pEd, EDBulkHead);
darran 0:55a05330f8cc 95 }
darran 0:55a05330f8cc 96
darran 0:55a05330f8cc 97 printf("\r\n--Ep Inst--\r\n");
darran 0:55a05330f8cc 98 m_pEd = /*new HCED(); // */m_pNextEd;
darran 0:55a05330f8cc 99
darran 0:55a05330f8cc 100 //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd);
darran 0:55a05330f8cc 101 m_pNextEd += 1; //TODO: Avail mem check
darran 0:55a05330f8cc 102 //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd);
darran 0:55a05330f8cc 103 #endif
darran 0:55a05330f8cc 104
darran 0:55a05330f8cc 105 m_pTdHead = m_tdPool.get();//new HCTD();
darran 0:55a05330f8cc 106 m_pTdTail = m_tdPool.get();//new HCTD();
darran 0:55a05330f8cc 107
darran 0:55a05330f8cc 108 printf("\r\n--m_pEd = %p--\r\n", m_pEd);
darran 0:55a05330f8cc 109
darran 0:55a05330f8cc 110 //Init Ed & Td
darran 0:55a05330f8cc 111 printf("\r\n--Ep Init--\r\n");
darran 0:55a05330f8cc 112 Host_EDInit(m_pEd);
darran 0:55a05330f8cc 113 printf("\r\n--Td Init--\r\n");
darran 0:55a05330f8cc 114 Host_TDInit(m_pTdHead);
darran 0:55a05330f8cc 115 Host_TDInit(m_pTdTail);
darran 0:55a05330f8cc 116
darran 0:55a05330f8cc 117 //Setup Ed
darran 0:55a05330f8cc 118 printf("\r\n--Ep Setup--\r\n");
darran 0:55a05330f8cc 119 m_pEd->Control = 1 | /* USB address */ //FIXME: Device Id
darran 0:55a05330f8cc 120 ((ep & 0x7F) << 7) | /* Endpoint address */
darran 0:55a05330f8cc 121 ((dir?2:1) << 11) | /* direction : Out = 1, 2 = In */
darran 0:55a05330f8cc 122 (size << 16); /* MaxPkt Size */
darran 0:55a05330f8cc 123
darran 0:55a05330f8cc 124 m_dir = dir;
darran 0:55a05330f8cc 125
darran 0:55a05330f8cc 126 m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list
darran 0:55a05330f8cc 127
darran 0:55a05330f8cc 128 printf("\r\n--Ep Reg--\r\n");
darran 0:55a05330f8cc 129 //Append Ed to bulk Ep list
darran 0:55a05330f8cc 130 #if 1
darran 0:55a05330f8cc 131 volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
darran 0:55a05330f8cc 132 m_pEd->Next = (USB_INT32U) prevEd;
darran 0:55a05330f8cc 133 LPC_USB->HcBulkHeadED = (USB_INT32U) m_pEd;
darran 0:55a05330f8cc 134 #else
darran 0:55a05330f8cc 135 if( LPC_USB->HcBulkHeadED == 0 )
darran 0:55a05330f8cc 136 {
darran 0:55a05330f8cc 137 LPC_USB->HcBulkHeadED = (USB_INT32U)m_pEd;
darran 0:55a05330f8cc 138 printf("\r\n--Bulk head--\r\n");
darran 0:55a05330f8cc 139 }
darran 0:55a05330f8cc 140 else
darran 0:55a05330f8cc 141 {
darran 0:55a05330f8cc 142 volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
darran 0:55a05330f8cc 143 while(prevEd->Next)
darran 0:55a05330f8cc 144 {
darran 0:55a05330f8cc 145 prevEd = (volatile HCED*) prevEd->Next;
darran 0:55a05330f8cc 146 }
darran 0:55a05330f8cc 147 printf("\r\n--Appended to ep list (prevEd = %p)--\r\n", prevEd);
darran 0:55a05330f8cc 148 prevEd->Next = (USB_INT32U) m_pEd;
darran 0:55a05330f8cc 149 }
darran 0:55a05330f8cc 150 #endif
darran 0:55a05330f8cc 151 /*
darran 0:55a05330f8cc 152 printf("\r\n--Writing config reg--\r\n");
darran 0:55a05330f8cc 153 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
darran 0:55a05330f8cc 154 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
darran 0:55a05330f8cc 155 */
darran 0:55a05330f8cc 156 }
darran 0:55a05330f8cc 157
darran 0:55a05330f8cc 158 UsbEndpoint::~UsbEndpoint()
darran 0:55a05330f8cc 159 {
darran 0:55a05330f8cc 160 m_pEd->Control |= ED_SKIP; //Skip this Ep in queue
darran 0:55a05330f8cc 161
darran 0:55a05330f8cc 162 //Remove from queue
darran 0:55a05330f8cc 163 if( LPC_USB->HcBulkHeadED == (USB_INT32U) m_pEd )
darran 0:55a05330f8cc 164 {
darran 0:55a05330f8cc 165 LPC_USB->HcBulkHeadED = m_pEd->Next;
darran 0:55a05330f8cc 166 }
darran 0:55a05330f8cc 167 else
darran 0:55a05330f8cc 168 {
darran 0:55a05330f8cc 169 volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
darran 0:55a05330f8cc 170 while( prevEd->Next != (USB_INT32U) m_pEd )
darran 0:55a05330f8cc 171 {
darran 0:55a05330f8cc 172 prevEd = (volatile HCED*) prevEd->Next;
darran 0:55a05330f8cc 173 }
darran 0:55a05330f8cc 174 prevEd->Next = m_pEd->Next;
darran 0:55a05330f8cc 175 }
darran 0:55a05330f8cc 176
darran 0:55a05330f8cc 177 if( LPC_USB->HcBulkCurrentED == (USB_INT32U) m_pEd )
darran 0:55a05330f8cc 178 {
darran 0:55a05330f8cc 179 LPC_USB->HcBulkCurrentED = 0;
darran 0:55a05330f8cc 180 }
darran 0:55a05330f8cc 181
darran 0:55a05330f8cc 182
darran 0:55a05330f8cc 183 #if 0 //NO WAY! Owned by pool!!!
darran 0:55a05330f8cc 184 delete m_pEd;
darran 0:55a05330f8cc 185 delete m_pTdHead;
darran 0:55a05330f8cc 186 delete m_pTdTail;
darran 0:55a05330f8cc 187 #endif
darran 0:55a05330f8cc 188 }
darran 0:55a05330f8cc 189
darran 0:55a05330f8cc 190 RC UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len)
darran 0:55a05330f8cc 191 {
darran 0:55a05330f8cc 192 if(!m_done)
darran 0:55a05330f8cc 193 return ERR_TD_FAIL;
darran 0:55a05330f8cc 194 volatile USB_INT32U token = (m_dir?TD_IN:TD_OUT);
darran 0:55a05330f8cc 195 //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail);
darran 0:55a05330f8cc 196
darran 0:55a05330f8cc 197 //Swap Tds
darran 0:55a05330f8cc 198 //printf("\r\n--Swap Tds--\r\n");
darran 0:55a05330f8cc 199 volatile HCTD* pTdSwap;
darran 0:55a05330f8cc 200 pTdSwap = m_pTdTail;
darran 0:55a05330f8cc 201 m_pTdTail = m_pTdHead;
darran 0:55a05330f8cc 202 m_pTdHead = pTdSwap;
darran 0:55a05330f8cc 203
darran 0:55a05330f8cc 204
darran 0:55a05330f8cc 205 // printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail);
darran 0:55a05330f8cc 206
darran 0:55a05330f8cc 207 // printf("\r\n--Tds setup--\r\n");
darran 0:55a05330f8cc 208 m_pTdHead->Control = (TD_ROUNDING |
darran 0:55a05330f8cc 209 token |
darran 0:55a05330f8cc 210 // TD_DELAY_INT(0) |
darran 0:55a05330f8cc 211 TD_DELAY_INT(7) |
darran 0:55a05330f8cc 212 TD_CC);
darran 0:55a05330f8cc 213 m_pTdTail->Control = 0;
darran 0:55a05330f8cc 214 m_pTdHead->CurrBufPtr = (USB_INT32U) buf;
darran 0:55a05330f8cc 215 m_pBufStartPtr = buf;
darran 0:55a05330f8cc 216 m_pTdTail->CurrBufPtr = 0;
darran 0:55a05330f8cc 217 m_pTdHead->Next = (USB_INT32U) m_pTdTail;
darran 0:55a05330f8cc 218 m_pTdTail->Next = 0;
darran 0:55a05330f8cc 219 m_pTdHead->BufEnd = (USB_INT32U)(buf + (len - 1));
darran 0:55a05330f8cc 220 m_pTdTail->BufEnd = 0;
darran 0:55a05330f8cc 221
darran 0:55a05330f8cc 222 // printf("\r\n--Ed setup--\r\n");
darran 0:55a05330f8cc 223 // m_pEd->HeadTd = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002);
darran 0:55a05330f8cc 224 m_pEd->HeadTd = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit
darran 0:55a05330f8cc 225 m_pEd->TailTd = (USB_INT32U)m_pTdTail;
darran 0:55a05330f8cc 226 /*
darran 0:55a05330f8cc 227 printf("\r\n--Swap Tds--\r\n");
darran 0:55a05330f8cc 228 volatile HCTD* pTdSwap;
darran 0:55a05330f8cc 229 pTdSwap = m_pTdTail;
darran 0:55a05330f8cc 230 m_pTdTail = m_pTdHead;
darran 0:55a05330f8cc 231 m_pTdHead = pTdSwap;
darran 0:55a05330f8cc 232 */
darran 0:55a05330f8cc 233 // ed->Next = 0;
darran 0:55a05330f8cc 234
darran 0:55a05330f8cc 235 //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail);
darran 0:55a05330f8cc 236
darran 0:55a05330f8cc 237 // printf("\r\n--Writing config reg--\r\n");
darran 0:55a05330f8cc 238 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
darran 0:55a05330f8cc 239 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
darran 0:55a05330f8cc 240
darran 0:55a05330f8cc 241 // printf("\r\n--Processing queue--\r\n");
darran 0:55a05330f8cc 242 // __WFI();
darran 0:55a05330f8cc 243 m_done = false;
darran 0:55a05330f8cc 244 m_len = len;
darran 0:55a05330f8cc 245 return PROCESSING;
darran 0:55a05330f8cc 246
darran 0:55a05330f8cc 247 }
darran 0:55a05330f8cc 248
darran 0:55a05330f8cc 249 RC UsbEndpoint::status()
darran 0:55a05330f8cc 250 {
darran 0:55a05330f8cc 251 if( m_done )
darran 0:55a05330f8cc 252 {
darran 0:55a05330f8cc 253 return OK;
darran 0:55a05330f8cc 254 }
darran 0:55a05330f8cc 255 //volatile HCTD* pTd = (volatile HCTD*) m_pEd->HeadTd;
darran 0:55a05330f8cc 256 //printf("\r\nm_pTdHead->CurrBufPtr = %16x", m_pTdHead->CurrBufPtr);
darran 0:55a05330f8cc 257 //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail);
darran 0:55a05330f8cc 258 //if( pTd->CurrBufPtr == 0 /*m_pEd->HeadTd != (USB_INT32U)m_pTdHead*//*m_pEd->HeadTd == (USB_INT32U)m_pTdTail*/) //Empty queue
darran 0:55a05330f8cc 259 else if( (m_pEd->HeadTd & ~0xF) == (USB_INT32U) m_pTdTail )
darran 0:55a05330f8cc 260 {
darran 0:55a05330f8cc 261 //Done
darran 0:55a05330f8cc 262 //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail);
darran 0:55a05330f8cc 263 int len;
darran 0:55a05330f8cc 264 if(m_pTdHead->CurrBufPtr)
darran 0:55a05330f8cc 265 len = m_pTdHead->CurrBufPtr - (USB_INT32U)m_pBufStartPtr; //Does not work properly, packet might have been discarded
darran 0:55a05330f8cc 266 else
darran 0:55a05330f8cc 267 len = m_len;
darran 0:55a05330f8cc 268 // printf("\r\nDone w/ len = %d (m_pTdHead->CurrBufPtr=%16x)\r\n", len, m_pTdHead->CurrBufPtr);
darran 0:55a05330f8cc 269 if(len == 0) //Packet transfered completely
darran 0:55a05330f8cc 270 len = m_len;
darran 0:55a05330f8cc 271 //Host_TDInit(m_pTdTail);
darran 0:55a05330f8cc 272 //m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list
darran 0:55a05330f8cc 273
darran 0:55a05330f8cc 274 // printf("\r\n--Writing config reg--\r\n");
darran 0:55a05330f8cc 275 //LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
darran 0:55a05330f8cc 276 //LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
darran 0:55a05330f8cc 277
darran 0:55a05330f8cc 278 m_done = true;
darran 0:55a05330f8cc 279 return len;
darran 0:55a05330f8cc 280 //return OK;
darran 0:55a05330f8cc 281 }
darran 0:55a05330f8cc 282 else if( m_pEd->HeadTd & 0x1 )
darran 0:55a05330f8cc 283 {
darran 0:55a05330f8cc 284 printf("\r\nHALTED!!\r\n");
darran 0:55a05330f8cc 285 return ERR_TD_FAIL;
darran 0:55a05330f8cc 286 }
darran 0:55a05330f8cc 287 else
darran 0:55a05330f8cc 288 {
darran 0:55a05330f8cc 289 // wait(1);
darran 0:55a05330f8cc 290 return PROCESSING;
darran 0:55a05330f8cc 291 }
darran 0:55a05330f8cc 292 }
darran 0:55a05330f8cc 293
darran 0:55a05330f8cc 294 #endif