Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UsbEndpoint.cpp Source File

UsbEndpoint.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "UsbEndpoint.h"
00025 
00026 #include "netCfg.h"
00027 #if NET_USB
00028 
00029 EdPool::EdPool(int size) : m_pos(0)
00030 {
00031   m_pool = new uint8_t[2*size*0x10];
00032   printf("\r\n--HCED* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10);
00033 }
00034 
00035 EdPool::~EdPool()
00036 {
00037   printf("\r\n--~EdPool()--\r\n");
00038   delete[] m_pool;
00039 }
00040 
00041 HCED* EdPool::get()
00042 {
00043   printf("\r\n--HCED* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]);
00044   while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 )
00045   {
00046     m_pos++;
00047   } 
00048   HCED* pEd = (HCED*) &m_pool[m_pos];
00049   m_pos += sizeof(HCED);
00050   printf("\r\n--HCED* pEd = %p--\r\n", pEd);
00051   return pEd;
00052 }
00053 
00054 TdPool::TdPool(int size) : m_pos(0)
00055 {
00056   m_pool = new uint8_t[2*size*0x10];
00057   printf("\r\n--HCTD* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10);
00058 }
00059 
00060 TdPool::~TdPool()
00061 {
00062   printf("\r\n--~EdPool()--\r\n");
00063   delete[] m_pool;
00064 }
00065 
00066 HCTD* TdPool::get()
00067 {
00068   printf("\r\n--HCTD* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]);
00069   while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 )
00070   {
00071     m_pos++;
00072   } 
00073   HCTD* pTd = (HCTD*) &m_pool[m_pos];
00074   m_pos += sizeof(HCTD);
00075   printf("\r\n--HCTD* pTd = %p--\r\n", pTd);
00076   return pTd;
00077 }
00078 //uint8_t TdPool::pool[16*0x10]={0};//Ok for 2 Eps (2*(2Tds/Ep*2Eps)) 
00079 //int TdPool::pos = 0;
00080 
00081 extern volatile HCED* EDBulkHead;
00082 //volatile HCED* UsbEndpoint::m_pNextEd = NULL;
00083 
00084 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)
00085 {
00086   #if 1
00087   
00088   m_pEd = m_edPool.get();
00089   
00090   #else
00091   if(m_pNextEd == NULL)
00092   {
00093     m_pNextEd = EDBulkHead;
00094     //printf("\r\n--m_pEd = %p < EDBulkHead = %p --\r\n", m_pEd, EDBulkHead);
00095   }
00096   
00097   printf("\r\n--Ep Inst--\r\n");
00098   m_pEd = /*new HCED(); // */m_pNextEd;
00099   
00100   //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd);
00101   m_pNextEd += 1; //TODO: Avail mem check
00102   //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd);
00103   #endif
00104   
00105   m_pTdHead = m_tdPool.get();//new HCTD();
00106   m_pTdTail = m_tdPool.get();//new HCTD();
00107   
00108   printf("\r\n--m_pEd = %p--\r\n", m_pEd);
00109   
00110   //Init Ed & Td
00111   printf("\r\n--Ep Init--\r\n");
00112   Host_EDInit(m_pEd);
00113   printf("\r\n--Td Init--\r\n");
00114   Host_TDInit(m_pTdHead);
00115   Host_TDInit(m_pTdTail);
00116   
00117   //Setup Ed
00118   printf("\r\n--Ep Setup--\r\n");
00119   m_pEd->Control =  1        |      /* USB address           */ //FIXME: Device Id
00120   ((ep & 0x7F) << 7)            |      /* Endpoint address      */
00121   ((dir?2:1) << 11)             |      /* direction : Out = 1, 2 = In */
00122   (size << 16);     /* MaxPkt Size           */
00123   
00124   m_dir = dir;
00125   
00126   m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list
00127   
00128   printf("\r\n--Ep Reg--\r\n");
00129   //Append Ed to bulk Ep list
00130   #if 1
00131   volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
00132   m_pEd->Next = (USB_INT32U) prevEd;
00133   LPC_USB->HcBulkHeadED = (USB_INT32U) m_pEd;
00134   #else
00135   if( LPC_USB->HcBulkHeadED == 0 )
00136   {
00137     LPC_USB->HcBulkHeadED = (USB_INT32U)m_pEd;
00138     printf("\r\n--Bulk head--\r\n");
00139   }
00140   else
00141   {
00142     volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
00143     while(prevEd->Next)
00144     {
00145       prevEd = (volatile HCED*) prevEd->Next;
00146     }
00147     printf("\r\n--Appended to ep list (prevEd = %p)--\r\n", prevEd);
00148     prevEd->Next = (USB_INT32U) m_pEd;
00149   }
00150   #endif
00151   /*
00152   printf("\r\n--Writing config reg--\r\n");
00153   LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
00154   LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_BLE;
00155   */
00156 }
00157 
00158 UsbEndpoint::~UsbEndpoint()
00159 {
00160   m_pEd->Control |= ED_SKIP; //Skip this Ep in queue
00161 
00162   //Remove from queue
00163   if( LPC_USB->HcBulkHeadED == (USB_INT32U) m_pEd )
00164   {
00165     LPC_USB->HcBulkHeadED = m_pEd->Next;
00166   }
00167   else
00168   {
00169     volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
00170     while( prevEd->Next != (USB_INT32U) m_pEd )
00171     {
00172       prevEd = (volatile HCED*) prevEd->Next;
00173     }
00174     prevEd->Next = m_pEd->Next;
00175   }
00176   
00177   if( LPC_USB->HcBulkCurrentED == (USB_INT32U) m_pEd )
00178   {
00179     LPC_USB->HcBulkCurrentED = 0;
00180   }
00181   
00182   
00183   #if 0 //NO WAY! Owned by pool!!!
00184   delete m_pEd;
00185   delete m_pTdHead;
00186   delete m_pTdTail;
00187   #endif
00188 }
00189 
00190 RC UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len)
00191 {
00192   if(!m_done)
00193     return ERR_TD_FAIL;
00194   volatile USB_INT32U token = (m_dir?TD_IN:TD_OUT);
00195   //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);
00196 
00197   //Swap Tds
00198   //printf("\r\n--Swap Tds--\r\n");
00199   volatile HCTD* pTdSwap;
00200   pTdSwap = m_pTdTail;
00201   m_pTdTail = m_pTdHead;
00202   m_pTdHead = pTdSwap;
00203   
00204   
00205   //  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);
00206   
00207   //  printf("\r\n--Tds setup--\r\n");
00208   m_pTdHead->Control = (TD_ROUNDING    |
00209                      token           |
00210                   //   TD_DELAY_INT(0) |         
00211                        TD_DELAY_INT(7) |                  
00212                      TD_CC);
00213   m_pTdTail->Control = 0;
00214   m_pTdHead->CurrBufPtr   = (USB_INT32U) buf;
00215   m_pBufStartPtr = buf;
00216   m_pTdTail->CurrBufPtr   = 0;
00217   m_pTdHead->Next         = (USB_INT32U) m_pTdTail;
00218   m_pTdTail->Next         = 0;
00219   m_pTdHead->BufEnd       = (USB_INT32U)(buf + (len - 1));
00220   m_pTdTail->BufEnd       = 0;
00221   
00222 //  printf("\r\n--Ed setup--\r\n");
00223 //  m_pEd->HeadTd  = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002);
00224   m_pEd->HeadTd  = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit
00225   m_pEd->TailTd  = (USB_INT32U)m_pTdTail;
00226 /*
00227   printf("\r\n--Swap Tds--\r\n");
00228   volatile HCTD* pTdSwap;
00229   pTdSwap = m_pTdTail;
00230   m_pTdTail = m_pTdHead;
00231   m_pTdHead = pTdSwap;
00232   */
00233 //  ed->Next    = 0;
00234 
00235   //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);
00236   
00237  // printf("\r\n--Writing config reg--\r\n");
00238   LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
00239   LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_BLE;
00240   
00241  // printf("\r\n--Processing queue--\r\n");
00242  // __WFI();
00243   m_done = false;
00244   m_len = len;
00245   return PROCESSING;
00246  
00247 }
00248   
00249 RC UsbEndpoint::status()
00250 {
00251   if( m_done )
00252   {
00253     return OK;
00254   }
00255   //volatile HCTD* pTd = (volatile HCTD*) m_pEd->HeadTd;
00256   //printf("\r\nm_pTdHead->CurrBufPtr = %16x", m_pTdHead->CurrBufPtr);
00257   //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);
00258   //if( pTd->CurrBufPtr == 0 /*m_pEd->HeadTd != (USB_INT32U)m_pTdHead*//*m_pEd->HeadTd == (USB_INT32U)m_pTdTail*/) //Empty queue
00259   else if( (m_pEd->HeadTd & ~0xF) == (USB_INT32U) m_pTdTail )
00260   {
00261     //Done
00262     //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);
00263     int len;
00264     if(m_pTdHead->CurrBufPtr)
00265       len = m_pTdHead->CurrBufPtr - (USB_INT32U)m_pBufStartPtr; //Does not work properly, packet might have been discarded
00266     else
00267       len = m_len;
00268 //    printf("\r\nDone w/ len = %d (m_pTdHead->CurrBufPtr=%16x)\r\n", len, m_pTdHead->CurrBufPtr);
00269     if(len == 0) //Packet transfered completely
00270       len = m_len;
00271     //Host_TDInit(m_pTdTail);
00272     //m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list
00273     
00274    // printf("\r\n--Writing config reg--\r\n");
00275     //LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
00276     //LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_BLE;
00277    
00278     m_done = true;
00279     return len; 
00280     //return OK;
00281   }
00282   else if( m_pEd->HeadTd & 0x1 )
00283   {
00284     printf("\r\nHALTED!!\r\n");
00285     return ERR_TD_FAIL;
00286   }
00287   else
00288   { 
00289    // wait(1);
00290     return PROCESSING;
00291   }
00292 }
00293 
00294 #endif