Darran Shepherd
/
AutoIpNetStack
Net stack with AutoIP enabled
Embed:
(wiki syntax)
Show/hide line numbers
usbhost_lpc17xx.c
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 /* 00025 ************************************************************************************************************** 00026 * NXP USB Host Stack 00027 * 00028 * (c) Copyright 2008, NXP SemiConductors 00029 * (c) Copyright 2008, OnChip Technologies LLC 00030 * All Rights Reserved 00031 * 00032 * www.nxp.com 00033 * www.onchiptech.com 00034 * 00035 * File : usbhost_lpc17xx.c 00036 * Programmer(s) : Ravikanth.P 00037 * Version : 00038 * 00039 ************************************************************************************************************** 00040 */ 00041 00042 /* 00043 ************************************************************************************************************** 00044 * INCLUDE HEADER FILES 00045 ************************************************************************************************************** 00046 */ 00047 00048 #include "netCfg.h" 00049 #if NET_USB 00050 00051 #ifdef __cplusplus 00052 extern "C" { 00053 #endif 00054 00055 #include "usbhost_lpc17xx.h" 00056 //#include "UsbEndpoint.h" 00057 00058 /* 00059 ************************************************************************************************************** 00060 * GLOBAL VARIABLES 00061 ************************************************************************************************************** 00062 */ 00063 int gUSBConnected; 00064 00065 volatile USB_INT32U HOST_RhscIntr = 0; /* Root Hub Status Change interrupt */ 00066 volatile USB_INT32U HOST_WdhIntr = 0; /* Semaphore to wait until the TD is submitted */ 00067 volatile USB_INT08U HOST_TDControlStatus = 0; 00068 volatile HCED *EDCtrl; /* Control endpoint descriptor structure */ 00069 //volatile HCED *EDBulkHead; 00070 //volatile HCED *EDBulkIn; /* BulkIn endpoint descriptor structure */ 00071 //volatile HCED *EDBulkOut; /* BulkOut endpoint descriptor structure */ 00072 volatile HCTD *TDHead; /* Head transfer descriptor structure */ 00073 volatile HCTD *TDTail; /* Tail transfer descriptor structure */ 00074 volatile HCCA *Hcca; /* Host Controller Communications Area structure */ 00075 USB_INT16U *TDBufNonVol; /* Identical to TDBuffer just to reduce compiler warnings */ 00076 volatile USB_INT08U *TDBuffer; /* Current Buffer Pointer of transfer descriptor */ 00077 00078 // USB host structures 00079 // AHB SRAM block 1 00080 #define HOSTBASEADDR 0x2007C000 00081 // reserve memory for the linker 00082 static USB_INT08U HostBuf[0x300] __attribute((section("AHBSRAM1"),aligned))/* __attribute__((at(HOSTBASEADDR)))*/; 00083 /* 00084 ************************************************************************************************************** 00085 * DELAY IN MILLI SECONDS 00086 * 00087 * Description: This function provides a delay in milli seconds 00088 * 00089 * Arguments : delay The delay required 00090 * 00091 * Returns : None 00092 * 00093 ************************************************************************************************************** 00094 */ 00095 00096 void Host_DelayMS (USB_INT32U delay) 00097 { 00098 volatile USB_INT32U i; 00099 00100 00101 for (i = 0; i < delay; i++) { 00102 Host_DelayUS(1000); 00103 } 00104 } 00105 00106 /* 00107 ************************************************************************************************************** 00108 * DELAY IN MICRO SECONDS 00109 * 00110 * Description: This function provides a delay in micro seconds 00111 * 00112 * Arguments : delay The delay required 00113 * 00114 * Returns : None 00115 * 00116 ************************************************************************************************************** 00117 */ 00118 00119 void Host_DelayUS (USB_INT32U delay) 00120 { 00121 volatile USB_INT32U i; 00122 00123 for (i = 0; i < (4 * delay); i++) { /* This logic was tested. It gives app. 1 micro sec delay */ 00124 ; 00125 } 00126 00127 } 00128 00129 // bits of the USB/OTG clock control register 00130 #define HOST_CLK_EN (1<<0) 00131 #define DEV_CLK_EN (1<<1) 00132 #define PORTSEL_CLK_EN (1<<3) 00133 #define AHB_CLK_EN (1<<4) 00134 00135 // bits of the USB/OTG clock status register 00136 #define HOST_CLK_ON (1<<0) 00137 #define DEV_CLK_ON (1<<1) 00138 #define PORTSEL_CLK_ON (1<<3) 00139 #define AHB_CLK_ON (1<<4) 00140 00141 // we need host clock, OTG/portsel clock and AHB clock 00142 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN) 00143 00144 /* 00145 ************************************************************************************************************** 00146 * INITIALIZE THE HOST CONTROLLER 00147 * 00148 * Description: This function initializes lpc17xx host controller 00149 * 00150 * Arguments : None 00151 * 00152 * Returns : 00153 * 00154 ************************************************************************************************************** 00155 */ 00156 void Host_Init (void) 00157 { 00158 PRINT_Log("In Host_Init\n"); 00159 NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */ 00160 00161 // turn on power for USB 00162 LPC_SC->PCONP |= (1UL<<31); 00163 // Enable USB host clock, port selection and AHB clock 00164 LPC_USB->USBClkCtrl |= CLOCK_MASK; 00165 // Wait for clocks to become available 00166 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK) 00167 ; 00168 00169 // it seems the bits[0:1] mean the following 00170 // 0: U1=device, U2=host 00171 // 1: U1=host, U2=host 00172 // 2: reserved 00173 // 3: U1=host, U2=device 00174 // NB: this register is only available if OTG clock (aka "port select") is enabled!! 00175 // since we don't care about port 2, set just bit 0 to 1 (U1=host) 00176 LPC_USB->OTGStCtrl |= 1; 00177 00178 // now that we've configured the ports, we can turn off the portsel clock 00179 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; 00180 00181 // power pins are not connected on mbed, so we can skip them 00182 /* P1[18] = USB_UP_LED, 01 */ 00183 /* P1[19] = /USB_PPWR, 10 */ 00184 /* P1[22] = USB_PWRD, 10 */ 00185 /* P1[27] = /USB_OVRCR, 10 */ 00186 /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22)); 00187 LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080 00188 */ 00189 00190 // configure USB D+/D- pins 00191 /* P0[29] = USB_D+, 01 */ 00192 /* P0[30] = USB_D-, 01 */ 00193 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); 00194 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000 00195 00196 PRINT_Log("Initializing Host Stack\n"); 00197 00198 Hcca = (volatile HCCA *)(HostBuf+0x000); 00199 TDHead = (volatile HCTD *)(HostBuf+0x100); 00200 TDTail = (volatile HCTD *)(HostBuf+0x110); 00201 EDCtrl = (volatile HCED *)(HostBuf+0x120); 00202 //Space for Bulk Eps 00203 // EDBulkHead = (volatile HCED *)(HostBuf+0x130); 00204 // EDBulkIn = (volatile HCED *)(HostBuf+0x130); 00205 // EDBulkOut = (volatile HCED *)(HostBuf+0x140); 00206 // TDBuffer = (volatile USB_INT08U *)(HostBuf+0x150); 00207 TDBuffer = (volatile USB_INT08U *)(HostBuf+0x130); 00208 00209 // printf("\r\n--EDBulkHead = %p--\r\n", EDBulkHead); 00210 printf("\r\n--TDBuffer = %p--\r\n", TDBuffer); 00211 00212 /* Initialize all the TDs, EDs and HCCA to 0 */ 00213 Host_EDInit(EDCtrl); 00214 // Host_EDInit(EDBulkIn); 00215 // Host_EDInit(EDBulkOut); 00216 /* Host_TDInit(TDHead); 00217 Host_TDInit(TDTail);*/ 00218 Host_HCCAInit(Hcca); 00219 00220 Host_DelayMS(50); /* Wait 50 ms before apply reset */ 00221 LPC_USB->HcControl = 0; /* HARDWARE RESET */ 00222 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */ 00223 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */ 00224 00225 /* SOFTWARE RESET */ 00226 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; 00227 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */ 00228 00229 /* Put HC in operational state */ 00230 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; 00231 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */ 00232 00233 LPC_USB->HcHCCA = (USB_INT32U)Hcca; 00234 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ 00235 00236 00237 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | 00238 OR_INTR_ENABLE_WDH | 00239 OR_INTR_ENABLE_RHSC; 00240 00241 NVIC_SetPriority(USB_IRQn, 0); /* highest priority */ 00242 /* Enable the USB Interrupt */ 00243 NVIC_EnableIRQ(USB_IRQn); 00244 PRINT_Log("Host Initialized\n"); 00245 } 00246 00247 /* 00248 ************************************************************************************************************** 00249 * INTERRUPT SERVICE ROUTINE 00250 * 00251 * Description: This function services the interrupt caused by host controller 00252 * 00253 * Arguments : None 00254 * 00255 * Returns : None 00256 * 00257 ************************************************************************************************************** 00258 */ 00259 00260 void USB_IRQHandler (void) __irq 00261 { 00262 USB_INT32U int_status; 00263 USB_INT32U ie_status; 00264 00265 int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */ 00266 ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */ 00267 00268 if (!(int_status & ie_status)) { 00269 return; 00270 } else { 00271 00272 int_status = int_status & ie_status; 00273 if (int_status & OR_INTR_STATUS_RHSC) { /* Root hub status change interrupt */ 00274 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) { 00275 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) { 00276 /* 00277 * When DRWE is on, Connect Status Change 00278 * means a remote wakeup event. 00279 */ 00280 HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT 00281 } 00282 else { 00283 /* 00284 * When DRWE is off, Connect Status Change 00285 * is NOT a remote wakeup event 00286 */ 00287 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) { 00288 if (!gUSBConnected) { 00289 HOST_TDControlStatus = 0; 00290 HOST_WdhIntr = 0; 00291 HOST_RhscIntr = 1; 00292 gUSBConnected = 1; 00293 } 00294 else 00295 PRINT_Log("Spurious status change (connected)?\n"); 00296 } else { 00297 if (gUSBConnected) { 00298 LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts??? 00299 HOST_RhscIntr = 0; 00300 gUSBConnected = 0; 00301 } 00302 else 00303 PRINT_Log("Spurious status change (disconnected)?\n"); 00304 } 00305 } 00306 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; 00307 } 00308 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) { 00309 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; 00310 } 00311 } 00312 if (int_status & OR_INTR_STATUS_WDH) { /* Writeback Done Head interrupt */ 00313 HOST_WdhIntr = 1; 00314 HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf; 00315 //UsbEndpoint Cb : TODO 00316 //UsbEndpoint::completed(); 00317 } 00318 LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */ 00319 } 00320 return; 00321 } 00322 00323 /* 00324 ************************************************************************************************************** 00325 * PROCESS TRANSFER DESCRIPTOR 00326 * 00327 * Description: This function processes the transfer descriptor 00328 * 00329 * Arguments : ed Endpoint descriptor that contains this transfer descriptor 00330 * token SETUP, IN, OUT 00331 * buffer Current Buffer Pointer of the transfer descriptor 00332 * buffer_len Length of the buffer 00333 * 00334 * Returns : OK if TD submission is successful 00335 * ERROR if TD submission fails 00336 * 00337 ************************************************************************************************************** 00338 */ 00339 00340 volatile USB_INT32U h; 00341 00342 USB_INT32S Host_TDresult(volatile HCED *ed, 00343 volatile USB_INT32U token) 00344 { 00345 if(HOST_WdhIntr) 00346 HOST_WdhIntr = 0; 00347 else 00348 __WFI(); 00349 00350 if(ed->HeadTd == h) 00351 { 00352 return PROCESSING; 00353 } 00354 00355 if (!HOST_TDControlStatus) { 00356 return (OK); 00357 } else { 00358 return (ERR_TD_FAIL); 00359 } 00360 } 00361 00362 USB_INT32S Host_ProcessTD (volatile HCED *ed, 00363 volatile USB_INT32U token, 00364 volatile USB_INT08U *buffer, 00365 USB_INT32U buffer_len, 00366 bool block /* = true */ ) 00367 { 00368 volatile USB_INT32U td_toggle; 00369 00370 00371 if (ed == EDCtrl) { 00372 if (token == TD_SETUP) { 00373 td_toggle = TD_TOGGLE_0; 00374 } else { 00375 td_toggle = TD_TOGGLE_1; 00376 } 00377 } else { 00378 td_toggle = 0; 00379 } 00380 TDHead->Control = (TD_ROUNDING | 00381 token | 00382 TD_DELAY_INT(0) | 00383 td_toggle | 00384 TD_CC); 00385 TDTail->Control = 0; 00386 TDHead->CurrBufPtr = (USB_INT32U) buffer; 00387 TDTail->CurrBufPtr = 0; 00388 TDHead->Next = (USB_INT32U) TDTail; 00389 TDTail->Next = 0; 00390 TDHead->BufEnd = (USB_INT32U)(buffer + (buffer_len - 1)); 00391 TDTail->BufEnd = 0; 00392 00393 h = ed->HeadTd = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002); 00394 ed->TailTd = (USB_INT32U)TDTail; 00395 ed->Next = 0; 00396 00397 if (ed == EDCtrl) { 00398 LPC_USB->HcControlHeadED = (USB_INT32U)ed; 00399 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF; 00400 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; 00401 } else { 00402 LPC_USB->HcBulkHeadED = (USB_INT32U)ed; 00403 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; 00404 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; 00405 } 00406 00407 if(block) 00408 { 00409 while(ed->HeadTd == h) 00410 { 00411 Host_WDHWait(); 00412 } 00413 } 00414 else 00415 { 00416 return PROCESSING; 00417 } 00418 00419 // if (!(TDHead->Control & 0xF0000000)) { 00420 if (!HOST_TDControlStatus) { 00421 return (OK); 00422 } else { 00423 return (ERR_TD_FAIL); 00424 } 00425 } 00426 00427 /* 00428 ************************************************************************************************************** 00429 * ENUMERATE THE DEVICE 00430 * 00431 * Description: This function is used to enumerate the device connected 00432 * 00433 * Arguments : None 00434 * 00435 * Returns : None 00436 * 00437 ************************************************************************************************************** 00438 */ 00439 00440 USB_INT32S Host_EnumDev (void) 00441 { 00442 USB_INT32S rc; 00443 00444 PRINT_Log("\r\nConnect a device\r\n"); 00445 while (!HOST_RhscIntr) 00446 __WFI(); 00447 Host_DelayMS(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */ 00448 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset 00449 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) 00450 __WFI(); // Wait for port reset to complete... 00451 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal 00452 Host_DelayMS(200); /* Wait for 100 MS after port reset */ 00453 00454 EDCtrl->Control = 8 << 16; /* Put max pkt size = 8 */ 00455 /* Read first 8 bytes of device desc */ 00456 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8); 00457 if (rc != OK) { 00458 PRINT_Err(rc); 00459 return (rc); 00460 } 00461 EDCtrl->Control = TDBuffer[7] << 16; /* Get max pkt size of endpoint 0 */ 00462 rc = HOST_SET_ADDRESS(1); /* Set the device address to 1 */ 00463 if (rc != OK) { 00464 PRINT_Err(rc); 00465 return (rc); 00466 } 00467 Host_DelayMS(2); 00468 EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */ 00469 00470 /**/ 00471 00472 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor 00473 if (rc != OK) { 00474 PRINT_Err(rc); 00475 return (rc); 00476 } 00477 00478 rc = SerialCheckVidPid(); 00479 if (rc != OK) { 00480 PRINT_Err(rc); 00481 return (rc); 00482 } 00483 /**/ 00484 /* Get the configuration descriptor */ 00485 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9); 00486 if (rc != OK) { 00487 PRINT_Err(rc); 00488 return (rc); 00489 } 00490 /* Get the first configuration data */ 00491 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2])); 00492 if (rc != OK) { 00493 PRINT_Err(rc); 00494 return (rc); 00495 } 00496 #ifdef MS 00497 rc = MS_ParseConfiguration(); /* Parse the configuration */ 00498 if (rc != OK) { 00499 PRINT_Err(rc); 00500 return (rc); 00501 } 00502 #endif 00503 PRINT_Log("\r\nParsing cfg\r\n"); 00504 rc = SerialParseConfig(); /* Parse the configuration */ 00505 if (rc != OK) { 00506 PRINT_Err(rc); 00507 return (rc); 00508 } 00509 00510 rc = USBH_SET_CONFIGURATION(1); /* Select device configuration 1 */ 00511 if (rc != OK) { 00512 PRINT_Err(rc); 00513 } 00514 Host_DelayMS(100); /* Some devices may require this delay */ 00515 return (rc); 00516 } 00517 00518 /* 00519 ************************************************************************************************************** 00520 * RECEIVE THE CONTROL INFORMATION 00521 * 00522 * Description: This function is used to receive the control information 00523 * 00524 * Arguments : bm_request_type 00525 * b_request 00526 * w_value 00527 * w_index 00528 * w_length 00529 * buffer 00530 * 00531 * Returns : OK if Success 00532 * ERROR if Failed 00533 * 00534 ************************************************************************************************************** 00535 */ 00536 00537 USB_INT32S Host_CtrlRecv ( USB_INT08U bm_request_type, 00538 USB_INT08U b_request, 00539 USB_INT16U w_value, 00540 USB_INT16U w_index, 00541 USB_INT16U w_length, 00542 volatile USB_INT08U *buffer) 00543 { 00544 USB_INT32S rc; 00545 00546 00547 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length); 00548 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8); 00549 if (rc == OK) { 00550 if (w_length) { 00551 rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length); 00552 } 00553 if (rc == OK) { 00554 rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0); 00555 } 00556 } 00557 return (rc); 00558 } 00559 00560 /* 00561 ************************************************************************************************************** 00562 * SEND THE CONTROL INFORMATION 00563 * 00564 * Description: This function is used to send the control information 00565 * 00566 * Arguments : None 00567 * 00568 * Returns : OK if Success 00569 * ERR_INVALID_BOOTSIG if Failed 00570 * 00571 ************************************************************************************************************** 00572 */ 00573 00574 USB_INT32S Host_CtrlSend ( USB_INT08U bm_request_type, 00575 USB_INT08U b_request, 00576 USB_INT16U w_value, 00577 USB_INT16U w_index, 00578 USB_INT16U w_length, 00579 volatile USB_INT08U *buffer) 00580 { 00581 USB_INT32S rc; 00582 00583 00584 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length); 00585 00586 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8); 00587 if (rc == OK) { 00588 if (w_length) { 00589 rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length); 00590 } 00591 if (rc == OK) { 00592 rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0); 00593 } 00594 } 00595 return (rc); 00596 } 00597 00598 /* 00599 ************************************************************************************************************** 00600 * FILL SETUP PACKET 00601 * 00602 * Description: This function is used to fill the setup packet 00603 * 00604 * Arguments : None 00605 * 00606 * Returns : OK if Success 00607 * ERR_INVALID_BOOTSIG if Failed 00608 * 00609 ************************************************************************************************************** 00610 */ 00611 00612 void Host_FillSetup (USB_INT08U bm_request_type, 00613 USB_INT08U b_request, 00614 USB_INT16U w_value, 00615 USB_INT16U w_index, 00616 USB_INT16U w_length) 00617 { 00618 int i; 00619 for (i=0;i<w_length;i++) 00620 TDBuffer[i] = 0; 00621 00622 TDBuffer[0] = bm_request_type; 00623 TDBuffer[1] = b_request; 00624 WriteLE16U(&TDBuffer[2], w_value); 00625 WriteLE16U(&TDBuffer[4], w_index); 00626 WriteLE16U(&TDBuffer[6], w_length); 00627 } 00628 00629 00630 00631 /* 00632 ************************************************************************************************************** 00633 * INITIALIZE THE TRANSFER DESCRIPTOR 00634 * 00635 * Description: This function initializes transfer descriptor 00636 * 00637 * Arguments : Pointer to TD structure 00638 * 00639 * Returns : None 00640 * 00641 ************************************************************************************************************** 00642 */ 00643 00644 void Host_TDInit (volatile HCTD *td) 00645 { 00646 00647 td->Control = 0; 00648 td->CurrBufPtr = 0; 00649 td->Next = 0; 00650 td->BufEnd = 0; 00651 } 00652 00653 /* 00654 ************************************************************************************************************** 00655 * INITIALIZE THE ENDPOINT DESCRIPTOR 00656 * 00657 * Description: This function initializes endpoint descriptor 00658 * 00659 * Arguments : Pointer to ED strcuture 00660 * 00661 * Returns : None 00662 * 00663 ************************************************************************************************************** 00664 */ 00665 00666 void Host_EDInit (volatile HCED *ed) 00667 { 00668 00669 ed->Control = 0; 00670 ed->TailTd = 0; 00671 ed->HeadTd = 0; 00672 ed->Next = 0; 00673 } 00674 00675 /* 00676 ************************************************************************************************************** 00677 * INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA 00678 * 00679 * Description: This function initializes host controller communications area 00680 * 00681 * Arguments : Pointer to HCCA 00682 * 00683 * Returns : 00684 * 00685 ************************************************************************************************************** 00686 */ 00687 00688 void Host_HCCAInit (volatile HCCA *hcca) 00689 { 00690 USB_INT32U i; 00691 00692 00693 for (i = 0; i < 32; i++) { 00694 00695 hcca->IntTable[i] = 0; 00696 hcca->FrameNumber = 0; 00697 hcca->DoneHead = 0; 00698 } 00699 00700 } 00701 00702 /* 00703 ************************************************************************************************************** 00704 * WAIT FOR WDH INTERRUPT 00705 * 00706 * Description: This function is infinite loop which breaks when ever a WDH interrupt rises 00707 * 00708 * Arguments : None 00709 * 00710 * Returns : None 00711 * 00712 ************************************************************************************************************** 00713 */ 00714 00715 void Host_WDHWait (void) 00716 { 00717 while (!HOST_WdhIntr) 00718 __WFI(); 00719 00720 HOST_WdhIntr = 0; 00721 } 00722 00723 /* 00724 ************************************************************************************************************** 00725 * READ LE 32U 00726 * 00727 * Description: This function is used to read an unsigned integer from a character buffer in the platform 00728 * containing little endian processor 00729 * 00730 * Arguments : pmem Pointer to the character buffer 00731 * 00732 * Returns : val Unsigned integer 00733 * 00734 ************************************************************************************************************** 00735 */ 00736 00737 USB_INT32U ReadLE32U (volatile USB_INT08U *pmem) 00738 { 00739 USB_INT32U val = *(USB_INT32U*)pmem; 00740 #ifdef __BIG_ENDIAN 00741 return __REV(val); 00742 #else 00743 return val; 00744 #endif 00745 } 00746 00747 /* 00748 ************************************************************************************************************** 00749 * WRITE LE 32U 00750 * 00751 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform 00752 * containing little endian processor. 00753 * 00754 * Arguments : pmem Pointer to the charecter buffer 00755 * val Integer value to be placed in the charecter buffer 00756 * 00757 * Returns : None 00758 * 00759 ************************************************************************************************************** 00760 */ 00761 00762 void WriteLE32U (volatile USB_INT08U *pmem, 00763 USB_INT32U val) 00764 { 00765 #ifdef __BIG_ENDIAN 00766 *(USB_INT32U*)pmem = __REV(val); 00767 #else 00768 *(USB_INT32U*)pmem = val; 00769 #endif 00770 } 00771 00772 /* 00773 ************************************************************************************************************** 00774 * READ LE 16U 00775 * 00776 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform 00777 * containing little endian processor 00778 * 00779 * Arguments : pmem Pointer to the charecter buffer 00780 * 00781 * Returns : val Unsigned short integer 00782 * 00783 ************************************************************************************************************** 00784 */ 00785 00786 USB_INT16U ReadLE16U (volatile USB_INT08U *pmem) 00787 { 00788 USB_INT16U val = *(USB_INT16U*)pmem; 00789 #ifdef __BIG_ENDIAN 00790 return __REV16(val); 00791 #else 00792 return val; 00793 #endif 00794 } 00795 00796 /* 00797 ************************************************************************************************************** 00798 * WRITE LE 16U 00799 * 00800 * Description: This function is used to write an unsigned short integer into a charecter buffer in the 00801 * platform containing little endian processor 00802 * 00803 * Arguments : pmem Pointer to the charecter buffer 00804 * val Value to be placed in the charecter buffer 00805 * 00806 * Returns : None 00807 * 00808 ************************************************************************************************************** 00809 */ 00810 00811 void WriteLE16U (volatile USB_INT08U *pmem, 00812 USB_INT16U val) 00813 { 00814 #ifdef __BIG_ENDIAN 00815 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF); 00816 #else 00817 *(USB_INT16U*)pmem = val; 00818 #endif 00819 } 00820 00821 /* 00822 ************************************************************************************************************** 00823 * READ BE 32U 00824 * 00825 * Description: This function is used to read an unsigned integer from a charecter buffer in the platform 00826 * containing big endian processor 00827 * 00828 * Arguments : pmem Pointer to the charecter buffer 00829 * 00830 * Returns : val Unsigned integer 00831 * 00832 ************************************************************************************************************** 00833 */ 00834 00835 USB_INT32U ReadBE32U (volatile USB_INT08U *pmem) 00836 { 00837 USB_INT32U val = *(USB_INT32U*)pmem; 00838 #ifdef __BIG_ENDIAN 00839 return val; 00840 #else 00841 return __REV(val); 00842 #endif 00843 } 00844 00845 /* 00846 ************************************************************************************************************** 00847 * WRITE BE 32U 00848 * 00849 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform 00850 * containing big endian processor 00851 * 00852 * Arguments : pmem Pointer to the charecter buffer 00853 * val Value to be placed in the charecter buffer 00854 * 00855 * Returns : None 00856 * 00857 ************************************************************************************************************** 00858 */ 00859 00860 void WriteBE32U (volatile USB_INT08U *pmem, 00861 USB_INT32U val) 00862 { 00863 #ifdef __BIG_ENDIAN 00864 *(USB_INT32U*)pmem = val; 00865 #else 00866 *(USB_INT32U*)pmem = __REV(val); 00867 #endif 00868 } 00869 00870 /* 00871 ************************************************************************************************************** 00872 * READ BE 16U 00873 * 00874 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform 00875 * containing big endian processor 00876 * 00877 * Arguments : pmem Pointer to the charecter buffer 00878 * 00879 * Returns : val Unsigned short integer 00880 * 00881 ************************************************************************************************************** 00882 */ 00883 00884 USB_INT16U ReadBE16U (volatile USB_INT08U *pmem) 00885 { 00886 USB_INT16U val = *(USB_INT16U*)pmem; 00887 #ifdef __BIG_ENDIAN 00888 return val; 00889 #else 00890 return __REV16(val); 00891 #endif 00892 } 00893 00894 /* 00895 ************************************************************************************************************** 00896 * WRITE BE 16U 00897 * 00898 * Description: This function is used to write an unsigned short integer into the charecter buffer in the 00899 * platform containing big endian processor 00900 * 00901 * Arguments : pmem Pointer to the charecter buffer 00902 * val Value to be placed in the charecter buffer 00903 * 00904 * Returns : None 00905 * 00906 ************************************************************************************************************** 00907 */ 00908 00909 void WriteBE16U (volatile USB_INT08U *pmem, 00910 USB_INT16U val) 00911 { 00912 #ifdef __BIG_ENDIAN 00913 *(USB_INT16U*)pmem = val; 00914 #else 00915 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF); 00916 #endif 00917 } 00918 00919 #ifdef __cplusplus 00920 } 00921 #endif 00922 00923 #endif
Generated on Tue Jul 12 2022 15:37:05 by 1.7.2