Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Committer:
iva2k
Date:
Mon Jun 14 03:24:33 2010 +0000
Revision:
1:3ee499525aa5
Parent:
0:e614f7875b60

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:e614f7875b60 1
iva2k 0:e614f7875b60 2 /*
iva2k 0:e614f7875b60 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
iva2k 0:e614f7875b60 4
iva2k 0:e614f7875b60 5 Permission is hereby granted, free of charge, to any person obtaining a copy
iva2k 0:e614f7875b60 6 of this software and associated documentation files (the "Software"), to deal
iva2k 0:e614f7875b60 7 in the Software without restriction, including without limitation the rights
iva2k 0:e614f7875b60 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
iva2k 0:e614f7875b60 9 copies of the Software, and to permit persons to whom the Software is
iva2k 0:e614f7875b60 10 furnished to do so, subject to the following conditions:
iva2k 0:e614f7875b60 11
iva2k 0:e614f7875b60 12 The above copyright notice and this permission notice shall be included in
iva2k 0:e614f7875b60 13 all copies or substantial portions of the Software.
iva2k 0:e614f7875b60 14
iva2k 0:e614f7875b60 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
iva2k 0:e614f7875b60 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
iva2k 0:e614f7875b60 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
iva2k 0:e614f7875b60 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
iva2k 0:e614f7875b60 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
iva2k 0:e614f7875b60 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
iva2k 0:e614f7875b60 21 THE SOFTWARE.
iva2k 0:e614f7875b60 22 */
iva2k 0:e614f7875b60 23
iva2k 0:e614f7875b60 24 /*
iva2k 0:e614f7875b60 25 **************************************************************************************************************
iva2k 0:e614f7875b60 26 * NXP USB Host Stack
iva2k 0:e614f7875b60 27 *
iva2k 0:e614f7875b60 28 * (c) Copyright 2008, NXP SemiConductors
iva2k 0:e614f7875b60 29 * (c) Copyright 2008, OnChip Technologies LLC
iva2k 0:e614f7875b60 30 * All Rights Reserved
iva2k 0:e614f7875b60 31 *
iva2k 0:e614f7875b60 32 * www.nxp.com
iva2k 0:e614f7875b60 33 * www.onchiptech.com
iva2k 0:e614f7875b60 34 *
iva2k 0:e614f7875b60 35 * File : usbhost_lpc17xx.c
iva2k 0:e614f7875b60 36 * Programmer(s) : Ravikanth.P
iva2k 0:e614f7875b60 37 * Version :
iva2k 0:e614f7875b60 38 *
iva2k 0:e614f7875b60 39 **************************************************************************************************************
iva2k 0:e614f7875b60 40 */
iva2k 0:e614f7875b60 41
iva2k 0:e614f7875b60 42 /*
iva2k 0:e614f7875b60 43 **************************************************************************************************************
iva2k 0:e614f7875b60 44 * INCLUDE HEADER FILES
iva2k 0:e614f7875b60 45 **************************************************************************************************************
iva2k 0:e614f7875b60 46 */
iva2k 0:e614f7875b60 47
iva2k 0:e614f7875b60 48 #include "netCfg.h"
iva2k 0:e614f7875b60 49 #if NET_USB
iva2k 0:e614f7875b60 50
iva2k 0:e614f7875b60 51 #ifdef __cplusplus
iva2k 0:e614f7875b60 52 extern "C" {
iva2k 0:e614f7875b60 53 #endif
iva2k 0:e614f7875b60 54
iva2k 0:e614f7875b60 55 #include "usbhost_lpc17xx.h"
iva2k 0:e614f7875b60 56 //#include "UsbEndpoint.h"
iva2k 0:e614f7875b60 57
iva2k 0:e614f7875b60 58 /*
iva2k 0:e614f7875b60 59 **************************************************************************************************************
iva2k 0:e614f7875b60 60 * GLOBAL VARIABLES
iva2k 0:e614f7875b60 61 **************************************************************************************************************
iva2k 0:e614f7875b60 62 */
iva2k 0:e614f7875b60 63 int gUSBConnected;
iva2k 0:e614f7875b60 64
iva2k 0:e614f7875b60 65 volatile USB_INT32U HOST_RhscIntr = 0; /* Root Hub Status Change interrupt */
iva2k 0:e614f7875b60 66 volatile USB_INT32U HOST_WdhIntr = 0; /* Semaphore to wait until the TD is submitted */
iva2k 0:e614f7875b60 67 volatile USB_INT08U HOST_TDControlStatus = 0;
iva2k 0:e614f7875b60 68 volatile HCED *EDCtrl; /* Control endpoint descriptor structure */
iva2k 0:e614f7875b60 69 //volatile HCED *EDBulkHead;
iva2k 0:e614f7875b60 70 //volatile HCED *EDBulkIn; /* BulkIn endpoint descriptor structure */
iva2k 0:e614f7875b60 71 //volatile HCED *EDBulkOut; /* BulkOut endpoint descriptor structure */
iva2k 0:e614f7875b60 72 volatile HCTD *TDHead; /* Head transfer descriptor structure */
iva2k 0:e614f7875b60 73 volatile HCTD *TDTail; /* Tail transfer descriptor structure */
iva2k 0:e614f7875b60 74 volatile HCCA *Hcca; /* Host Controller Communications Area structure */
iva2k 0:e614f7875b60 75 USB_INT16U *TDBufNonVol; /* Identical to TDBuffer just to reduce compiler warnings */
iva2k 0:e614f7875b60 76 volatile USB_INT08U *TDBuffer; /* Current Buffer Pointer of transfer descriptor */
iva2k 0:e614f7875b60 77
iva2k 0:e614f7875b60 78 // USB host structures
iva2k 0:e614f7875b60 79 // AHB SRAM block 1
iva2k 0:e614f7875b60 80 #define HOSTBASEADDR 0x2007C000
iva2k 0:e614f7875b60 81 // reserve memory for the linker
iva2k 0:e614f7875b60 82 static USB_INT08U HostBuf[0x300] __attribute((section("AHBSRAM1"),aligned))/* __attribute__((at(HOSTBASEADDR)))*/;
iva2k 0:e614f7875b60 83 /*
iva2k 0:e614f7875b60 84 **************************************************************************************************************
iva2k 0:e614f7875b60 85 * DELAY IN MILLI SECONDS
iva2k 0:e614f7875b60 86 *
iva2k 0:e614f7875b60 87 * Description: This function provides a delay in milli seconds
iva2k 0:e614f7875b60 88 *
iva2k 0:e614f7875b60 89 * Arguments : delay The delay required
iva2k 0:e614f7875b60 90 *
iva2k 0:e614f7875b60 91 * Returns : None
iva2k 0:e614f7875b60 92 *
iva2k 0:e614f7875b60 93 **************************************************************************************************************
iva2k 0:e614f7875b60 94 */
iva2k 0:e614f7875b60 95
iva2k 0:e614f7875b60 96 void Host_DelayMS (USB_INT32U delay)
iva2k 0:e614f7875b60 97 {
iva2k 0:e614f7875b60 98 volatile USB_INT32U i;
iva2k 0:e614f7875b60 99
iva2k 0:e614f7875b60 100
iva2k 0:e614f7875b60 101 for (i = 0; i < delay; i++) {
iva2k 0:e614f7875b60 102 Host_DelayUS(1000);
iva2k 0:e614f7875b60 103 }
iva2k 0:e614f7875b60 104 }
iva2k 0:e614f7875b60 105
iva2k 0:e614f7875b60 106 /*
iva2k 0:e614f7875b60 107 **************************************************************************************************************
iva2k 0:e614f7875b60 108 * DELAY IN MICRO SECONDS
iva2k 0:e614f7875b60 109 *
iva2k 0:e614f7875b60 110 * Description: This function provides a delay in micro seconds
iva2k 0:e614f7875b60 111 *
iva2k 0:e614f7875b60 112 * Arguments : delay The delay required
iva2k 0:e614f7875b60 113 *
iva2k 0:e614f7875b60 114 * Returns : None
iva2k 0:e614f7875b60 115 *
iva2k 0:e614f7875b60 116 **************************************************************************************************************
iva2k 0:e614f7875b60 117 */
iva2k 0:e614f7875b60 118
iva2k 0:e614f7875b60 119 void Host_DelayUS (USB_INT32U delay)
iva2k 0:e614f7875b60 120 {
iva2k 0:e614f7875b60 121 volatile USB_INT32U i;
iva2k 0:e614f7875b60 122
iva2k 0:e614f7875b60 123 for (i = 0; i < (4 * delay); i++) { /* This logic was tested. It gives app. 1 micro sec delay */
iva2k 0:e614f7875b60 124 ;
iva2k 0:e614f7875b60 125 }
iva2k 0:e614f7875b60 126
iva2k 0:e614f7875b60 127 }
iva2k 0:e614f7875b60 128
iva2k 0:e614f7875b60 129 // bits of the USB/OTG clock control register
iva2k 0:e614f7875b60 130 #define HOST_CLK_EN (1<<0)
iva2k 0:e614f7875b60 131 #define DEV_CLK_EN (1<<1)
iva2k 0:e614f7875b60 132 #define PORTSEL_CLK_EN (1<<3)
iva2k 0:e614f7875b60 133 #define AHB_CLK_EN (1<<4)
iva2k 0:e614f7875b60 134
iva2k 0:e614f7875b60 135 // bits of the USB/OTG clock status register
iva2k 0:e614f7875b60 136 #define HOST_CLK_ON (1<<0)
iva2k 0:e614f7875b60 137 #define DEV_CLK_ON (1<<1)
iva2k 0:e614f7875b60 138 #define PORTSEL_CLK_ON (1<<3)
iva2k 0:e614f7875b60 139 #define AHB_CLK_ON (1<<4)
iva2k 0:e614f7875b60 140
iva2k 0:e614f7875b60 141 // we need host clock, OTG/portsel clock and AHB clock
iva2k 0:e614f7875b60 142 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
iva2k 0:e614f7875b60 143
iva2k 0:e614f7875b60 144 /*
iva2k 0:e614f7875b60 145 **************************************************************************************************************
iva2k 0:e614f7875b60 146 * INITIALIZE THE HOST CONTROLLER
iva2k 0:e614f7875b60 147 *
iva2k 0:e614f7875b60 148 * Description: This function initializes lpc17xx host controller
iva2k 0:e614f7875b60 149 *
iva2k 0:e614f7875b60 150 * Arguments : None
iva2k 0:e614f7875b60 151 *
iva2k 0:e614f7875b60 152 * Returns :
iva2k 0:e614f7875b60 153 *
iva2k 0:e614f7875b60 154 **************************************************************************************************************
iva2k 0:e614f7875b60 155 */
iva2k 0:e614f7875b60 156 void Host_Init (void)
iva2k 0:e614f7875b60 157 {
iva2k 0:e614f7875b60 158 PRINT_Log("In Host_Init\n");
iva2k 0:e614f7875b60 159 NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */
iva2k 0:e614f7875b60 160
iva2k 0:e614f7875b60 161 // turn on power for USB
iva2k 0:e614f7875b60 162 LPC_SC->PCONP |= (1UL<<31);
iva2k 0:e614f7875b60 163 // Enable USB host clock, port selection and AHB clock
iva2k 0:e614f7875b60 164 LPC_USB->USBClkCtrl |= CLOCK_MASK;
iva2k 0:e614f7875b60 165 // Wait for clocks to become available
iva2k 0:e614f7875b60 166 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
iva2k 0:e614f7875b60 167 ;
iva2k 0:e614f7875b60 168
iva2k 0:e614f7875b60 169 // it seems the bits[0:1] mean the following
iva2k 0:e614f7875b60 170 // 0: U1=device, U2=host
iva2k 0:e614f7875b60 171 // 1: U1=host, U2=host
iva2k 0:e614f7875b60 172 // 2: reserved
iva2k 0:e614f7875b60 173 // 3: U1=host, U2=device
iva2k 0:e614f7875b60 174 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
iva2k 0:e614f7875b60 175 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
iva2k 0:e614f7875b60 176 LPC_USB->OTGStCtrl |= 1;
iva2k 0:e614f7875b60 177
iva2k 0:e614f7875b60 178 // now that we've configured the ports, we can turn off the portsel clock
iva2k 0:e614f7875b60 179 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
iva2k 0:e614f7875b60 180
iva2k 0:e614f7875b60 181 // power pins are not connected on mbed, so we can skip them
iva2k 0:e614f7875b60 182 /* P1[18] = USB_UP_LED, 01 */
iva2k 0:e614f7875b60 183 /* P1[19] = /USB_PPWR, 10 */
iva2k 0:e614f7875b60 184 /* P1[22] = USB_PWRD, 10 */
iva2k 0:e614f7875b60 185 /* P1[27] = /USB_OVRCR, 10 */
iva2k 0:e614f7875b60 186 /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));
iva2k 0:e614f7875b60 187 LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080
iva2k 0:e614f7875b60 188 */
iva2k 0:e614f7875b60 189
iva2k 0:e614f7875b60 190 // configure USB D+/D- pins
iva2k 0:e614f7875b60 191 /* P0[29] = USB_D+, 01 */
iva2k 0:e614f7875b60 192 /* P0[30] = USB_D-, 01 */
iva2k 0:e614f7875b60 193 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
iva2k 0:e614f7875b60 194 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
iva2k 0:e614f7875b60 195
iva2k 0:e614f7875b60 196 PRINT_Log("Initializing Host Stack\n");
iva2k 0:e614f7875b60 197
iva2k 0:e614f7875b60 198 Hcca = (volatile HCCA *)(HostBuf+0x000);
iva2k 0:e614f7875b60 199 TDHead = (volatile HCTD *)(HostBuf+0x100);
iva2k 0:e614f7875b60 200 TDTail = (volatile HCTD *)(HostBuf+0x110);
iva2k 0:e614f7875b60 201 EDCtrl = (volatile HCED *)(HostBuf+0x120);
iva2k 0:e614f7875b60 202 //Space for Bulk Eps
iva2k 0:e614f7875b60 203 // EDBulkHead = (volatile HCED *)(HostBuf+0x130);
iva2k 0:e614f7875b60 204 // EDBulkIn = (volatile HCED *)(HostBuf+0x130);
iva2k 0:e614f7875b60 205 // EDBulkOut = (volatile HCED *)(HostBuf+0x140);
iva2k 0:e614f7875b60 206 // TDBuffer = (volatile USB_INT08U *)(HostBuf+0x150);
iva2k 0:e614f7875b60 207 TDBuffer = (volatile USB_INT08U *)(HostBuf+0x130);
iva2k 0:e614f7875b60 208
iva2k 0:e614f7875b60 209 // printf("\r\n--EDBulkHead = %p--\r\n", EDBulkHead);
iva2k 0:e614f7875b60 210 printf("\r\n--TDBuffer = %p--\r\n", TDBuffer);
iva2k 0:e614f7875b60 211
iva2k 0:e614f7875b60 212 /* Initialize all the TDs, EDs and HCCA to 0 */
iva2k 0:e614f7875b60 213 Host_EDInit(EDCtrl);
iva2k 0:e614f7875b60 214 // Host_EDInit(EDBulkIn);
iva2k 0:e614f7875b60 215 // Host_EDInit(EDBulkOut);
iva2k 0:e614f7875b60 216 /* Host_TDInit(TDHead);
iva2k 0:e614f7875b60 217 Host_TDInit(TDTail);*/
iva2k 0:e614f7875b60 218 Host_HCCAInit(Hcca);
iva2k 0:e614f7875b60 219
iva2k 0:e614f7875b60 220 Host_DelayMS(50); /* Wait 50 ms before apply reset */
iva2k 0:e614f7875b60 221 LPC_USB->HcControl = 0; /* HARDWARE RESET */
iva2k 0:e614f7875b60 222 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */
iva2k 0:e614f7875b60 223 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */
iva2k 0:e614f7875b60 224
iva2k 0:e614f7875b60 225 /* SOFTWARE RESET */
iva2k 0:e614f7875b60 226 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
iva2k 0:e614f7875b60 227 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
iva2k 0:e614f7875b60 228
iva2k 0:e614f7875b60 229 /* Put HC in operational state */
iva2k 0:e614f7875b60 230 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
iva2k 0:e614f7875b60 231 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
iva2k 0:e614f7875b60 232
iva2k 0:e614f7875b60 233 LPC_USB->HcHCCA = (USB_INT32U)Hcca;
iva2k 0:e614f7875b60 234 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */
iva2k 0:e614f7875b60 235
iva2k 0:e614f7875b60 236
iva2k 0:e614f7875b60 237 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE |
iva2k 0:e614f7875b60 238 OR_INTR_ENABLE_WDH |
iva2k 0:e614f7875b60 239 OR_INTR_ENABLE_RHSC;
iva2k 0:e614f7875b60 240
iva2k 0:e614f7875b60 241 NVIC_SetPriority(USB_IRQn, 0); /* highest priority */
iva2k 0:e614f7875b60 242 /* Enable the USB Interrupt */
iva2k 0:e614f7875b60 243 NVIC_EnableIRQ(USB_IRQn);
iva2k 0:e614f7875b60 244 PRINT_Log("Host Initialized\n");
iva2k 0:e614f7875b60 245 }
iva2k 0:e614f7875b60 246
iva2k 0:e614f7875b60 247 /*
iva2k 0:e614f7875b60 248 **************************************************************************************************************
iva2k 0:e614f7875b60 249 * INTERRUPT SERVICE ROUTINE
iva2k 0:e614f7875b60 250 *
iva2k 0:e614f7875b60 251 * Description: This function services the interrupt caused by host controller
iva2k 0:e614f7875b60 252 *
iva2k 0:e614f7875b60 253 * Arguments : None
iva2k 0:e614f7875b60 254 *
iva2k 0:e614f7875b60 255 * Returns : None
iva2k 0:e614f7875b60 256 *
iva2k 0:e614f7875b60 257 **************************************************************************************************************
iva2k 0:e614f7875b60 258 */
iva2k 0:e614f7875b60 259
iva2k 0:e614f7875b60 260 void USB_IRQHandler (void) __irq
iva2k 0:e614f7875b60 261 {
iva2k 0:e614f7875b60 262 USB_INT32U int_status;
iva2k 0:e614f7875b60 263 USB_INT32U ie_status;
iva2k 0:e614f7875b60 264
iva2k 0:e614f7875b60 265 int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */
iva2k 0:e614f7875b60 266 ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */
iva2k 0:e614f7875b60 267
iva2k 0:e614f7875b60 268 if (!(int_status & ie_status)) {
iva2k 0:e614f7875b60 269 return;
iva2k 0:e614f7875b60 270 } else {
iva2k 0:e614f7875b60 271
iva2k 0:e614f7875b60 272 int_status = int_status & ie_status;
iva2k 0:e614f7875b60 273 if (int_status & OR_INTR_STATUS_RHSC) { /* Root hub status change interrupt */
iva2k 0:e614f7875b60 274 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
iva2k 0:e614f7875b60 275 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
iva2k 0:e614f7875b60 276 /*
iva2k 0:e614f7875b60 277 * When DRWE is on, Connect Status Change
iva2k 0:e614f7875b60 278 * means a remote wakeup event.
iva2k 0:e614f7875b60 279 */
iva2k 0:e614f7875b60 280 HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
iva2k 0:e614f7875b60 281 }
iva2k 0:e614f7875b60 282 else {
iva2k 0:e614f7875b60 283 /*
iva2k 0:e614f7875b60 284 * When DRWE is off, Connect Status Change
iva2k 0:e614f7875b60 285 * is NOT a remote wakeup event
iva2k 0:e614f7875b60 286 */
iva2k 0:e614f7875b60 287 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
iva2k 0:e614f7875b60 288 if (!gUSBConnected) {
iva2k 0:e614f7875b60 289 HOST_TDControlStatus = 0;
iva2k 0:e614f7875b60 290 HOST_WdhIntr = 0;
iva2k 0:e614f7875b60 291 HOST_RhscIntr = 1;
iva2k 0:e614f7875b60 292 gUSBConnected = 1;
iva2k 0:e614f7875b60 293 }
iva2k 0:e614f7875b60 294 else
iva2k 0:e614f7875b60 295 PRINT_Log("Spurious status change (connected)?\n");
iva2k 0:e614f7875b60 296 } else {
iva2k 0:e614f7875b60 297 if (gUSBConnected) {
iva2k 0:e614f7875b60 298 LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts???
iva2k 0:e614f7875b60 299 HOST_RhscIntr = 0;
iva2k 0:e614f7875b60 300 gUSBConnected = 0;
iva2k 0:e614f7875b60 301 }
iva2k 0:e614f7875b60 302 else
iva2k 0:e614f7875b60 303 PRINT_Log("Spurious status change (disconnected)?\n");
iva2k 0:e614f7875b60 304 }
iva2k 0:e614f7875b60 305 }
iva2k 0:e614f7875b60 306 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
iva2k 0:e614f7875b60 307 }
iva2k 0:e614f7875b60 308 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
iva2k 0:e614f7875b60 309 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
iva2k 0:e614f7875b60 310 }
iva2k 0:e614f7875b60 311 }
iva2k 0:e614f7875b60 312 if (int_status & OR_INTR_STATUS_WDH) { /* Writeback Done Head interrupt */
iva2k 0:e614f7875b60 313 HOST_WdhIntr = 1;
iva2k 0:e614f7875b60 314 HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf;
iva2k 0:e614f7875b60 315 //UsbEndpoint Cb : TODO
iva2k 0:e614f7875b60 316 //UsbEndpoint::completed();
iva2k 0:e614f7875b60 317 }
iva2k 0:e614f7875b60 318 LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */
iva2k 0:e614f7875b60 319 }
iva2k 0:e614f7875b60 320 return;
iva2k 0:e614f7875b60 321 }
iva2k 0:e614f7875b60 322
iva2k 0:e614f7875b60 323 /*
iva2k 0:e614f7875b60 324 **************************************************************************************************************
iva2k 0:e614f7875b60 325 * PROCESS TRANSFER DESCRIPTOR
iva2k 0:e614f7875b60 326 *
iva2k 0:e614f7875b60 327 * Description: This function processes the transfer descriptor
iva2k 0:e614f7875b60 328 *
iva2k 0:e614f7875b60 329 * Arguments : ed Endpoint descriptor that contains this transfer descriptor
iva2k 0:e614f7875b60 330 * token SETUP, IN, OUT
iva2k 0:e614f7875b60 331 * buffer Current Buffer Pointer of the transfer descriptor
iva2k 0:e614f7875b60 332 * buffer_len Length of the buffer
iva2k 0:e614f7875b60 333 *
iva2k 0:e614f7875b60 334 * Returns : OK if TD submission is successful
iva2k 0:e614f7875b60 335 * ERROR if TD submission fails
iva2k 0:e614f7875b60 336 *
iva2k 0:e614f7875b60 337 **************************************************************************************************************
iva2k 0:e614f7875b60 338 */
iva2k 0:e614f7875b60 339
iva2k 0:e614f7875b60 340 volatile USB_INT32U h;
iva2k 0:e614f7875b60 341
iva2k 0:e614f7875b60 342 USB_INT32S Host_TDresult(volatile HCED *ed,
iva2k 0:e614f7875b60 343 volatile USB_INT32U token)
iva2k 0:e614f7875b60 344 {
iva2k 0:e614f7875b60 345 if(HOST_WdhIntr)
iva2k 0:e614f7875b60 346 HOST_WdhIntr = 0;
iva2k 0:e614f7875b60 347 else
iva2k 0:e614f7875b60 348 __WFI();
iva2k 0:e614f7875b60 349
iva2k 0:e614f7875b60 350 if(ed->HeadTd == h)
iva2k 0:e614f7875b60 351 {
iva2k 0:e614f7875b60 352 return PROCESSING;
iva2k 0:e614f7875b60 353 }
iva2k 0:e614f7875b60 354
iva2k 0:e614f7875b60 355 if (!HOST_TDControlStatus) {
iva2k 0:e614f7875b60 356 return (OK);
iva2k 0:e614f7875b60 357 } else {
iva2k 0:e614f7875b60 358 return (ERR_TD_FAIL);
iva2k 0:e614f7875b60 359 }
iva2k 0:e614f7875b60 360 }
iva2k 0:e614f7875b60 361
iva2k 0:e614f7875b60 362 USB_INT32S Host_ProcessTD (volatile HCED *ed,
iva2k 0:e614f7875b60 363 volatile USB_INT32U token,
iva2k 0:e614f7875b60 364 volatile USB_INT08U *buffer,
iva2k 0:e614f7875b60 365 USB_INT32U buffer_len,
iva2k 0:e614f7875b60 366 bool block /* = true */ )
iva2k 0:e614f7875b60 367 {
iva2k 0:e614f7875b60 368 volatile USB_INT32U td_toggle;
iva2k 0:e614f7875b60 369
iva2k 0:e614f7875b60 370
iva2k 0:e614f7875b60 371 if (ed == EDCtrl) {
iva2k 0:e614f7875b60 372 if (token == TD_SETUP) {
iva2k 0:e614f7875b60 373 td_toggle = TD_TOGGLE_0;
iva2k 0:e614f7875b60 374 } else {
iva2k 0:e614f7875b60 375 td_toggle = TD_TOGGLE_1;
iva2k 0:e614f7875b60 376 }
iva2k 0:e614f7875b60 377 } else {
iva2k 0:e614f7875b60 378 td_toggle = 0;
iva2k 0:e614f7875b60 379 }
iva2k 0:e614f7875b60 380 TDHead->Control = (TD_ROUNDING |
iva2k 0:e614f7875b60 381 token |
iva2k 0:e614f7875b60 382 TD_DELAY_INT(0) |
iva2k 0:e614f7875b60 383 td_toggle |
iva2k 0:e614f7875b60 384 TD_CC);
iva2k 0:e614f7875b60 385 TDTail->Control = 0;
iva2k 0:e614f7875b60 386 TDHead->CurrBufPtr = (USB_INT32U) buffer;
iva2k 0:e614f7875b60 387 TDTail->CurrBufPtr = 0;
iva2k 0:e614f7875b60 388 TDHead->Next = (USB_INT32U) TDTail;
iva2k 0:e614f7875b60 389 TDTail->Next = 0;
iva2k 0:e614f7875b60 390 TDHead->BufEnd = (USB_INT32U)(buffer + (buffer_len - 1));
iva2k 0:e614f7875b60 391 TDTail->BufEnd = 0;
iva2k 0:e614f7875b60 392
iva2k 0:e614f7875b60 393 h = ed->HeadTd = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002);
iva2k 0:e614f7875b60 394 ed->TailTd = (USB_INT32U)TDTail;
iva2k 0:e614f7875b60 395 ed->Next = 0;
iva2k 0:e614f7875b60 396
iva2k 0:e614f7875b60 397 if (ed == EDCtrl) {
iva2k 0:e614f7875b60 398 LPC_USB->HcControlHeadED = (USB_INT32U)ed;
iva2k 0:e614f7875b60 399 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
iva2k 0:e614f7875b60 400 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE;
iva2k 0:e614f7875b60 401 } else {
iva2k 0:e614f7875b60 402 LPC_USB->HcBulkHeadED = (USB_INT32U)ed;
iva2k 0:e614f7875b60 403 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
iva2k 0:e614f7875b60 404 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
iva2k 0:e614f7875b60 405 }
iva2k 0:e614f7875b60 406
iva2k 0:e614f7875b60 407 if(block)
iva2k 0:e614f7875b60 408 {
iva2k 0:e614f7875b60 409 while(ed->HeadTd == h)
iva2k 0:e614f7875b60 410 {
iva2k 0:e614f7875b60 411 Host_WDHWait();
iva2k 0:e614f7875b60 412 }
iva2k 0:e614f7875b60 413 }
iva2k 0:e614f7875b60 414 else
iva2k 0:e614f7875b60 415 {
iva2k 0:e614f7875b60 416 return PROCESSING;
iva2k 0:e614f7875b60 417 }
iva2k 0:e614f7875b60 418
iva2k 0:e614f7875b60 419 // if (!(TDHead->Control & 0xF0000000)) {
iva2k 0:e614f7875b60 420 if (!HOST_TDControlStatus) {
iva2k 0:e614f7875b60 421 return (OK);
iva2k 0:e614f7875b60 422 } else {
iva2k 0:e614f7875b60 423 return (ERR_TD_FAIL);
iva2k 0:e614f7875b60 424 }
iva2k 0:e614f7875b60 425 }
iva2k 0:e614f7875b60 426
iva2k 0:e614f7875b60 427 /*
iva2k 0:e614f7875b60 428 **************************************************************************************************************
iva2k 0:e614f7875b60 429 * ENUMERATE THE DEVICE
iva2k 0:e614f7875b60 430 *
iva2k 0:e614f7875b60 431 * Description: This function is used to enumerate the device connected
iva2k 0:e614f7875b60 432 *
iva2k 0:e614f7875b60 433 * Arguments : None
iva2k 0:e614f7875b60 434 *
iva2k 0:e614f7875b60 435 * Returns : None
iva2k 0:e614f7875b60 436 *
iva2k 0:e614f7875b60 437 **************************************************************************************************************
iva2k 0:e614f7875b60 438 */
iva2k 0:e614f7875b60 439
iva2k 0:e614f7875b60 440 USB_INT32S Host_EnumDev (void)
iva2k 0:e614f7875b60 441 {
iva2k 0:e614f7875b60 442 USB_INT32S rc;
iva2k 0:e614f7875b60 443
iva2k 0:e614f7875b60 444 PRINT_Log("\r\nConnect a device\r\n");
iva2k 0:e614f7875b60 445 while (!HOST_RhscIntr)
iva2k 0:e614f7875b60 446 __WFI();
iva2k 0:e614f7875b60 447 Host_DelayMS(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */
iva2k 0:e614f7875b60 448 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
iva2k 0:e614f7875b60 449 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
iva2k 0:e614f7875b60 450 __WFI(); // Wait for port reset to complete...
iva2k 0:e614f7875b60 451 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
iva2k 0:e614f7875b60 452 Host_DelayMS(200); /* Wait for 100 MS after port reset */
iva2k 0:e614f7875b60 453
iva2k 0:e614f7875b60 454 EDCtrl->Control = 8 << 16; /* Put max pkt size = 8 */
iva2k 0:e614f7875b60 455 /* Read first 8 bytes of device desc */
iva2k 0:e614f7875b60 456 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
iva2k 0:e614f7875b60 457 if (rc != OK) {
iva2k 0:e614f7875b60 458 PRINT_Err(rc);
iva2k 0:e614f7875b60 459 return (rc);
iva2k 0:e614f7875b60 460 }
iva2k 0:e614f7875b60 461 EDCtrl->Control = TDBuffer[7] << 16; /* Get max pkt size of endpoint 0 */
iva2k 0:e614f7875b60 462 rc = HOST_SET_ADDRESS(1); /* Set the device address to 1 */
iva2k 0:e614f7875b60 463 if (rc != OK) {
iva2k 0:e614f7875b60 464 PRINT_Err(rc);
iva2k 0:e614f7875b60 465 return (rc);
iva2k 0:e614f7875b60 466 }
iva2k 0:e614f7875b60 467 Host_DelayMS(2);
iva2k 0:e614f7875b60 468 EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
iva2k 0:e614f7875b60 469
iva2k 0:e614f7875b60 470 /**/
iva2k 0:e614f7875b60 471
iva2k 0:e614f7875b60 472 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor
iva2k 0:e614f7875b60 473 if (rc != OK) {
iva2k 0:e614f7875b60 474 PRINT_Err(rc);
iva2k 0:e614f7875b60 475 return (rc);
iva2k 0:e614f7875b60 476 }
iva2k 0:e614f7875b60 477
iva2k 0:e614f7875b60 478 rc = SerialCheckVidPid();
iva2k 0:e614f7875b60 479 if (rc != OK) {
iva2k 0:e614f7875b60 480 PRINT_Err(rc);
iva2k 0:e614f7875b60 481 return (rc);
iva2k 0:e614f7875b60 482 }
iva2k 0:e614f7875b60 483 /**/
iva2k 0:e614f7875b60 484 /* Get the configuration descriptor */
iva2k 0:e614f7875b60 485 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
iva2k 0:e614f7875b60 486 if (rc != OK) {
iva2k 0:e614f7875b60 487 PRINT_Err(rc);
iva2k 0:e614f7875b60 488 return (rc);
iva2k 0:e614f7875b60 489 }
iva2k 0:e614f7875b60 490 /* Get the first configuration data */
iva2k 0:e614f7875b60 491 rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2]));
iva2k 0:e614f7875b60 492 if (rc != OK) {
iva2k 0:e614f7875b60 493 PRINT_Err(rc);
iva2k 0:e614f7875b60 494 return (rc);
iva2k 0:e614f7875b60 495 }
iva2k 0:e614f7875b60 496 #ifdef MS
iva2k 0:e614f7875b60 497 rc = MS_ParseConfiguration(); /* Parse the configuration */
iva2k 0:e614f7875b60 498 if (rc != OK) {
iva2k 0:e614f7875b60 499 PRINT_Err(rc);
iva2k 0:e614f7875b60 500 return (rc);
iva2k 0:e614f7875b60 501 }
iva2k 0:e614f7875b60 502 #endif
iva2k 0:e614f7875b60 503 PRINT_Log("\r\nParsing cfg\r\n");
iva2k 0:e614f7875b60 504 rc = SerialParseConfig(); /* Parse the configuration */
iva2k 0:e614f7875b60 505 if (rc != OK) {
iva2k 0:e614f7875b60 506 PRINT_Err(rc);
iva2k 0:e614f7875b60 507 return (rc);
iva2k 0:e614f7875b60 508 }
iva2k 0:e614f7875b60 509
iva2k 0:e614f7875b60 510 rc = USBH_SET_CONFIGURATION(1); /* Select device configuration 1 */
iva2k 0:e614f7875b60 511 if (rc != OK) {
iva2k 0:e614f7875b60 512 PRINT_Err(rc);
iva2k 0:e614f7875b60 513 }
iva2k 0:e614f7875b60 514 Host_DelayMS(100); /* Some devices may require this delay */
iva2k 0:e614f7875b60 515 return (rc);
iva2k 0:e614f7875b60 516 }
iva2k 0:e614f7875b60 517
iva2k 0:e614f7875b60 518 /*
iva2k 0:e614f7875b60 519 **************************************************************************************************************
iva2k 0:e614f7875b60 520 * RECEIVE THE CONTROL INFORMATION
iva2k 0:e614f7875b60 521 *
iva2k 0:e614f7875b60 522 * Description: This function is used to receive the control information
iva2k 0:e614f7875b60 523 *
iva2k 0:e614f7875b60 524 * Arguments : bm_request_type
iva2k 0:e614f7875b60 525 * b_request
iva2k 0:e614f7875b60 526 * w_value
iva2k 0:e614f7875b60 527 * w_index
iva2k 0:e614f7875b60 528 * w_length
iva2k 0:e614f7875b60 529 * buffer
iva2k 0:e614f7875b60 530 *
iva2k 0:e614f7875b60 531 * Returns : OK if Success
iva2k 0:e614f7875b60 532 * ERROR if Failed
iva2k 0:e614f7875b60 533 *
iva2k 0:e614f7875b60 534 **************************************************************************************************************
iva2k 0:e614f7875b60 535 */
iva2k 0:e614f7875b60 536
iva2k 0:e614f7875b60 537 USB_INT32S Host_CtrlRecv ( USB_INT08U bm_request_type,
iva2k 0:e614f7875b60 538 USB_INT08U b_request,
iva2k 0:e614f7875b60 539 USB_INT16U w_value,
iva2k 0:e614f7875b60 540 USB_INT16U w_index,
iva2k 0:e614f7875b60 541 USB_INT16U w_length,
iva2k 0:e614f7875b60 542 volatile USB_INT08U *buffer)
iva2k 0:e614f7875b60 543 {
iva2k 0:e614f7875b60 544 USB_INT32S rc;
iva2k 0:e614f7875b60 545
iva2k 0:e614f7875b60 546
iva2k 0:e614f7875b60 547 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
iva2k 0:e614f7875b60 548 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
iva2k 0:e614f7875b60 549 if (rc == OK) {
iva2k 0:e614f7875b60 550 if (w_length) {
iva2k 0:e614f7875b60 551 rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length);
iva2k 0:e614f7875b60 552 }
iva2k 0:e614f7875b60 553 if (rc == OK) {
iva2k 0:e614f7875b60 554 rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0);
iva2k 0:e614f7875b60 555 }
iva2k 0:e614f7875b60 556 }
iva2k 0:e614f7875b60 557 return (rc);
iva2k 0:e614f7875b60 558 }
iva2k 0:e614f7875b60 559
iva2k 0:e614f7875b60 560 /*
iva2k 0:e614f7875b60 561 **************************************************************************************************************
iva2k 0:e614f7875b60 562 * SEND THE CONTROL INFORMATION
iva2k 0:e614f7875b60 563 *
iva2k 0:e614f7875b60 564 * Description: This function is used to send the control information
iva2k 0:e614f7875b60 565 *
iva2k 0:e614f7875b60 566 * Arguments : None
iva2k 0:e614f7875b60 567 *
iva2k 0:e614f7875b60 568 * Returns : OK if Success
iva2k 0:e614f7875b60 569 * ERR_INVALID_BOOTSIG if Failed
iva2k 0:e614f7875b60 570 *
iva2k 0:e614f7875b60 571 **************************************************************************************************************
iva2k 0:e614f7875b60 572 */
iva2k 0:e614f7875b60 573
iva2k 0:e614f7875b60 574 USB_INT32S Host_CtrlSend ( USB_INT08U bm_request_type,
iva2k 0:e614f7875b60 575 USB_INT08U b_request,
iva2k 0:e614f7875b60 576 USB_INT16U w_value,
iva2k 0:e614f7875b60 577 USB_INT16U w_index,
iva2k 0:e614f7875b60 578 USB_INT16U w_length,
iva2k 0:e614f7875b60 579 volatile USB_INT08U *buffer)
iva2k 0:e614f7875b60 580 {
iva2k 0:e614f7875b60 581 USB_INT32S rc;
iva2k 0:e614f7875b60 582
iva2k 0:e614f7875b60 583
iva2k 0:e614f7875b60 584 Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
iva2k 0:e614f7875b60 585
iva2k 0:e614f7875b60 586 rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
iva2k 0:e614f7875b60 587 if (rc == OK) {
iva2k 0:e614f7875b60 588 if (w_length) {
iva2k 0:e614f7875b60 589 rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length);
iva2k 0:e614f7875b60 590 }
iva2k 0:e614f7875b60 591 if (rc == OK) {
iva2k 0:e614f7875b60 592 rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0);
iva2k 0:e614f7875b60 593 }
iva2k 0:e614f7875b60 594 }
iva2k 0:e614f7875b60 595 return (rc);
iva2k 0:e614f7875b60 596 }
iva2k 0:e614f7875b60 597
iva2k 0:e614f7875b60 598 /*
iva2k 0:e614f7875b60 599 **************************************************************************************************************
iva2k 0:e614f7875b60 600 * FILL SETUP PACKET
iva2k 0:e614f7875b60 601 *
iva2k 0:e614f7875b60 602 * Description: This function is used to fill the setup packet
iva2k 0:e614f7875b60 603 *
iva2k 0:e614f7875b60 604 * Arguments : None
iva2k 0:e614f7875b60 605 *
iva2k 0:e614f7875b60 606 * Returns : OK if Success
iva2k 0:e614f7875b60 607 * ERR_INVALID_BOOTSIG if Failed
iva2k 0:e614f7875b60 608 *
iva2k 0:e614f7875b60 609 **************************************************************************************************************
iva2k 0:e614f7875b60 610 */
iva2k 0:e614f7875b60 611
iva2k 0:e614f7875b60 612 void Host_FillSetup (USB_INT08U bm_request_type,
iva2k 0:e614f7875b60 613 USB_INT08U b_request,
iva2k 0:e614f7875b60 614 USB_INT16U w_value,
iva2k 0:e614f7875b60 615 USB_INT16U w_index,
iva2k 0:e614f7875b60 616 USB_INT16U w_length)
iva2k 0:e614f7875b60 617 {
iva2k 0:e614f7875b60 618 int i;
iva2k 0:e614f7875b60 619 for (i=0;i<w_length;i++)
iva2k 0:e614f7875b60 620 TDBuffer[i] = 0;
iva2k 0:e614f7875b60 621
iva2k 0:e614f7875b60 622 TDBuffer[0] = bm_request_type;
iva2k 0:e614f7875b60 623 TDBuffer[1] = b_request;
iva2k 0:e614f7875b60 624 WriteLE16U(&TDBuffer[2], w_value);
iva2k 0:e614f7875b60 625 WriteLE16U(&TDBuffer[4], w_index);
iva2k 0:e614f7875b60 626 WriteLE16U(&TDBuffer[6], w_length);
iva2k 0:e614f7875b60 627 }
iva2k 0:e614f7875b60 628
iva2k 0:e614f7875b60 629
iva2k 0:e614f7875b60 630
iva2k 0:e614f7875b60 631 /*
iva2k 0:e614f7875b60 632 **************************************************************************************************************
iva2k 0:e614f7875b60 633 * INITIALIZE THE TRANSFER DESCRIPTOR
iva2k 0:e614f7875b60 634 *
iva2k 0:e614f7875b60 635 * Description: This function initializes transfer descriptor
iva2k 0:e614f7875b60 636 *
iva2k 0:e614f7875b60 637 * Arguments : Pointer to TD structure
iva2k 0:e614f7875b60 638 *
iva2k 0:e614f7875b60 639 * Returns : None
iva2k 0:e614f7875b60 640 *
iva2k 0:e614f7875b60 641 **************************************************************************************************************
iva2k 0:e614f7875b60 642 */
iva2k 0:e614f7875b60 643
iva2k 0:e614f7875b60 644 void Host_TDInit (volatile HCTD *td)
iva2k 0:e614f7875b60 645 {
iva2k 0:e614f7875b60 646
iva2k 0:e614f7875b60 647 td->Control = 0;
iva2k 0:e614f7875b60 648 td->CurrBufPtr = 0;
iva2k 0:e614f7875b60 649 td->Next = 0;
iva2k 0:e614f7875b60 650 td->BufEnd = 0;
iva2k 0:e614f7875b60 651 }
iva2k 0:e614f7875b60 652
iva2k 0:e614f7875b60 653 /*
iva2k 0:e614f7875b60 654 **************************************************************************************************************
iva2k 0:e614f7875b60 655 * INITIALIZE THE ENDPOINT DESCRIPTOR
iva2k 0:e614f7875b60 656 *
iva2k 0:e614f7875b60 657 * Description: This function initializes endpoint descriptor
iva2k 0:e614f7875b60 658 *
iva2k 0:e614f7875b60 659 * Arguments : Pointer to ED strcuture
iva2k 0:e614f7875b60 660 *
iva2k 0:e614f7875b60 661 * Returns : None
iva2k 0:e614f7875b60 662 *
iva2k 0:e614f7875b60 663 **************************************************************************************************************
iva2k 0:e614f7875b60 664 */
iva2k 0:e614f7875b60 665
iva2k 0:e614f7875b60 666 void Host_EDInit (volatile HCED *ed)
iva2k 0:e614f7875b60 667 {
iva2k 0:e614f7875b60 668
iva2k 0:e614f7875b60 669 ed->Control = 0;
iva2k 0:e614f7875b60 670 ed->TailTd = 0;
iva2k 0:e614f7875b60 671 ed->HeadTd = 0;
iva2k 0:e614f7875b60 672 ed->Next = 0;
iva2k 0:e614f7875b60 673 }
iva2k 0:e614f7875b60 674
iva2k 0:e614f7875b60 675 /*
iva2k 0:e614f7875b60 676 **************************************************************************************************************
iva2k 0:e614f7875b60 677 * INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA
iva2k 0:e614f7875b60 678 *
iva2k 0:e614f7875b60 679 * Description: This function initializes host controller communications area
iva2k 0:e614f7875b60 680 *
iva2k 0:e614f7875b60 681 * Arguments : Pointer to HCCA
iva2k 0:e614f7875b60 682 *
iva2k 0:e614f7875b60 683 * Returns :
iva2k 0:e614f7875b60 684 *
iva2k 0:e614f7875b60 685 **************************************************************************************************************
iva2k 0:e614f7875b60 686 */
iva2k 0:e614f7875b60 687
iva2k 0:e614f7875b60 688 void Host_HCCAInit (volatile HCCA *hcca)
iva2k 0:e614f7875b60 689 {
iva2k 0:e614f7875b60 690 USB_INT32U i;
iva2k 0:e614f7875b60 691
iva2k 0:e614f7875b60 692
iva2k 0:e614f7875b60 693 for (i = 0; i < 32; i++) {
iva2k 0:e614f7875b60 694
iva2k 0:e614f7875b60 695 hcca->IntTable[i] = 0;
iva2k 0:e614f7875b60 696 hcca->FrameNumber = 0;
iva2k 0:e614f7875b60 697 hcca->DoneHead = 0;
iva2k 0:e614f7875b60 698 }
iva2k 0:e614f7875b60 699
iva2k 0:e614f7875b60 700 }
iva2k 0:e614f7875b60 701
iva2k 0:e614f7875b60 702 /*
iva2k 0:e614f7875b60 703 **************************************************************************************************************
iva2k 0:e614f7875b60 704 * WAIT FOR WDH INTERRUPT
iva2k 0:e614f7875b60 705 *
iva2k 0:e614f7875b60 706 * Description: This function is infinite loop which breaks when ever a WDH interrupt rises
iva2k 0:e614f7875b60 707 *
iva2k 0:e614f7875b60 708 * Arguments : None
iva2k 0:e614f7875b60 709 *
iva2k 0:e614f7875b60 710 * Returns : None
iva2k 0:e614f7875b60 711 *
iva2k 0:e614f7875b60 712 **************************************************************************************************************
iva2k 0:e614f7875b60 713 */
iva2k 0:e614f7875b60 714
iva2k 0:e614f7875b60 715 void Host_WDHWait (void)
iva2k 0:e614f7875b60 716 {
iva2k 0:e614f7875b60 717 while (!HOST_WdhIntr)
iva2k 0:e614f7875b60 718 __WFI();
iva2k 0:e614f7875b60 719
iva2k 0:e614f7875b60 720 HOST_WdhIntr = 0;
iva2k 0:e614f7875b60 721 }
iva2k 0:e614f7875b60 722
iva2k 0:e614f7875b60 723 /*
iva2k 0:e614f7875b60 724 **************************************************************************************************************
iva2k 0:e614f7875b60 725 * READ LE 32U
iva2k 0:e614f7875b60 726 *
iva2k 0:e614f7875b60 727 * Description: This function is used to read an unsigned integer from a character buffer in the platform
iva2k 0:e614f7875b60 728 * containing little endian processor
iva2k 0:e614f7875b60 729 *
iva2k 0:e614f7875b60 730 * Arguments : pmem Pointer to the character buffer
iva2k 0:e614f7875b60 731 *
iva2k 0:e614f7875b60 732 * Returns : val Unsigned integer
iva2k 0:e614f7875b60 733 *
iva2k 0:e614f7875b60 734 **************************************************************************************************************
iva2k 0:e614f7875b60 735 */
iva2k 0:e614f7875b60 736
iva2k 0:e614f7875b60 737 USB_INT32U ReadLE32U (volatile USB_INT08U *pmem)
iva2k 0:e614f7875b60 738 {
iva2k 0:e614f7875b60 739 USB_INT32U val = *(USB_INT32U*)pmem;
iva2k 0:e614f7875b60 740 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 741 return __REV(val);
iva2k 0:e614f7875b60 742 #else
iva2k 0:e614f7875b60 743 return val;
iva2k 0:e614f7875b60 744 #endif
iva2k 0:e614f7875b60 745 }
iva2k 0:e614f7875b60 746
iva2k 0:e614f7875b60 747 /*
iva2k 0:e614f7875b60 748 **************************************************************************************************************
iva2k 0:e614f7875b60 749 * WRITE LE 32U
iva2k 0:e614f7875b60 750 *
iva2k 0:e614f7875b60 751 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform
iva2k 0:e614f7875b60 752 * containing little endian processor.
iva2k 0:e614f7875b60 753 *
iva2k 0:e614f7875b60 754 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 755 * val Integer value to be placed in the charecter buffer
iva2k 0:e614f7875b60 756 *
iva2k 0:e614f7875b60 757 * Returns : None
iva2k 0:e614f7875b60 758 *
iva2k 0:e614f7875b60 759 **************************************************************************************************************
iva2k 0:e614f7875b60 760 */
iva2k 0:e614f7875b60 761
iva2k 0:e614f7875b60 762 void WriteLE32U (volatile USB_INT08U *pmem,
iva2k 0:e614f7875b60 763 USB_INT32U val)
iva2k 0:e614f7875b60 764 {
iva2k 0:e614f7875b60 765 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 766 *(USB_INT32U*)pmem = __REV(val);
iva2k 0:e614f7875b60 767 #else
iva2k 0:e614f7875b60 768 *(USB_INT32U*)pmem = val;
iva2k 0:e614f7875b60 769 #endif
iva2k 0:e614f7875b60 770 }
iva2k 0:e614f7875b60 771
iva2k 0:e614f7875b60 772 /*
iva2k 0:e614f7875b60 773 **************************************************************************************************************
iva2k 0:e614f7875b60 774 * READ LE 16U
iva2k 0:e614f7875b60 775 *
iva2k 0:e614f7875b60 776 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
iva2k 0:e614f7875b60 777 * containing little endian processor
iva2k 0:e614f7875b60 778 *
iva2k 0:e614f7875b60 779 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 780 *
iva2k 0:e614f7875b60 781 * Returns : val Unsigned short integer
iva2k 0:e614f7875b60 782 *
iva2k 0:e614f7875b60 783 **************************************************************************************************************
iva2k 0:e614f7875b60 784 */
iva2k 0:e614f7875b60 785
iva2k 0:e614f7875b60 786 USB_INT16U ReadLE16U (volatile USB_INT08U *pmem)
iva2k 0:e614f7875b60 787 {
iva2k 0:e614f7875b60 788 USB_INT16U val = *(USB_INT16U*)pmem;
iva2k 0:e614f7875b60 789 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 790 return __REV16(val);
iva2k 0:e614f7875b60 791 #else
iva2k 0:e614f7875b60 792 return val;
iva2k 0:e614f7875b60 793 #endif
iva2k 0:e614f7875b60 794 }
iva2k 0:e614f7875b60 795
iva2k 0:e614f7875b60 796 /*
iva2k 0:e614f7875b60 797 **************************************************************************************************************
iva2k 0:e614f7875b60 798 * WRITE LE 16U
iva2k 0:e614f7875b60 799 *
iva2k 0:e614f7875b60 800 * Description: This function is used to write an unsigned short integer into a charecter buffer in the
iva2k 0:e614f7875b60 801 * platform containing little endian processor
iva2k 0:e614f7875b60 802 *
iva2k 0:e614f7875b60 803 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 804 * val Value to be placed in the charecter buffer
iva2k 0:e614f7875b60 805 *
iva2k 0:e614f7875b60 806 * Returns : None
iva2k 0:e614f7875b60 807 *
iva2k 0:e614f7875b60 808 **************************************************************************************************************
iva2k 0:e614f7875b60 809 */
iva2k 0:e614f7875b60 810
iva2k 0:e614f7875b60 811 void WriteLE16U (volatile USB_INT08U *pmem,
iva2k 0:e614f7875b60 812 USB_INT16U val)
iva2k 0:e614f7875b60 813 {
iva2k 0:e614f7875b60 814 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 815 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
iva2k 0:e614f7875b60 816 #else
iva2k 0:e614f7875b60 817 *(USB_INT16U*)pmem = val;
iva2k 0:e614f7875b60 818 #endif
iva2k 0:e614f7875b60 819 }
iva2k 0:e614f7875b60 820
iva2k 0:e614f7875b60 821 /*
iva2k 0:e614f7875b60 822 **************************************************************************************************************
iva2k 0:e614f7875b60 823 * READ BE 32U
iva2k 0:e614f7875b60 824 *
iva2k 0:e614f7875b60 825 * Description: This function is used to read an unsigned integer from a charecter buffer in the platform
iva2k 0:e614f7875b60 826 * containing big endian processor
iva2k 0:e614f7875b60 827 *
iva2k 0:e614f7875b60 828 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 829 *
iva2k 0:e614f7875b60 830 * Returns : val Unsigned integer
iva2k 0:e614f7875b60 831 *
iva2k 0:e614f7875b60 832 **************************************************************************************************************
iva2k 0:e614f7875b60 833 */
iva2k 0:e614f7875b60 834
iva2k 0:e614f7875b60 835 USB_INT32U ReadBE32U (volatile USB_INT08U *pmem)
iva2k 0:e614f7875b60 836 {
iva2k 0:e614f7875b60 837 USB_INT32U val = *(USB_INT32U*)pmem;
iva2k 0:e614f7875b60 838 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 839 return val;
iva2k 0:e614f7875b60 840 #else
iva2k 0:e614f7875b60 841 return __REV(val);
iva2k 0:e614f7875b60 842 #endif
iva2k 0:e614f7875b60 843 }
iva2k 0:e614f7875b60 844
iva2k 0:e614f7875b60 845 /*
iva2k 0:e614f7875b60 846 **************************************************************************************************************
iva2k 0:e614f7875b60 847 * WRITE BE 32U
iva2k 0:e614f7875b60 848 *
iva2k 0:e614f7875b60 849 * Description: This function is used to write an unsigned integer into a charecter buffer in the platform
iva2k 0:e614f7875b60 850 * containing big endian processor
iva2k 0:e614f7875b60 851 *
iva2k 0:e614f7875b60 852 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 853 * val Value to be placed in the charecter buffer
iva2k 0:e614f7875b60 854 *
iva2k 0:e614f7875b60 855 * Returns : None
iva2k 0:e614f7875b60 856 *
iva2k 0:e614f7875b60 857 **************************************************************************************************************
iva2k 0:e614f7875b60 858 */
iva2k 0:e614f7875b60 859
iva2k 0:e614f7875b60 860 void WriteBE32U (volatile USB_INT08U *pmem,
iva2k 0:e614f7875b60 861 USB_INT32U val)
iva2k 0:e614f7875b60 862 {
iva2k 0:e614f7875b60 863 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 864 *(USB_INT32U*)pmem = val;
iva2k 0:e614f7875b60 865 #else
iva2k 0:e614f7875b60 866 *(USB_INT32U*)pmem = __REV(val);
iva2k 0:e614f7875b60 867 #endif
iva2k 0:e614f7875b60 868 }
iva2k 0:e614f7875b60 869
iva2k 0:e614f7875b60 870 /*
iva2k 0:e614f7875b60 871 **************************************************************************************************************
iva2k 0:e614f7875b60 872 * READ BE 16U
iva2k 0:e614f7875b60 873 *
iva2k 0:e614f7875b60 874 * Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
iva2k 0:e614f7875b60 875 * containing big endian processor
iva2k 0:e614f7875b60 876 *
iva2k 0:e614f7875b60 877 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 878 *
iva2k 0:e614f7875b60 879 * Returns : val Unsigned short integer
iva2k 0:e614f7875b60 880 *
iva2k 0:e614f7875b60 881 **************************************************************************************************************
iva2k 0:e614f7875b60 882 */
iva2k 0:e614f7875b60 883
iva2k 0:e614f7875b60 884 USB_INT16U ReadBE16U (volatile USB_INT08U *pmem)
iva2k 0:e614f7875b60 885 {
iva2k 0:e614f7875b60 886 USB_INT16U val = *(USB_INT16U*)pmem;
iva2k 0:e614f7875b60 887 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 888 return val;
iva2k 0:e614f7875b60 889 #else
iva2k 0:e614f7875b60 890 return __REV16(val);
iva2k 0:e614f7875b60 891 #endif
iva2k 0:e614f7875b60 892 }
iva2k 0:e614f7875b60 893
iva2k 0:e614f7875b60 894 /*
iva2k 0:e614f7875b60 895 **************************************************************************************************************
iva2k 0:e614f7875b60 896 * WRITE BE 16U
iva2k 0:e614f7875b60 897 *
iva2k 0:e614f7875b60 898 * Description: This function is used to write an unsigned short integer into the charecter buffer in the
iva2k 0:e614f7875b60 899 * platform containing big endian processor
iva2k 0:e614f7875b60 900 *
iva2k 0:e614f7875b60 901 * Arguments : pmem Pointer to the charecter buffer
iva2k 0:e614f7875b60 902 * val Value to be placed in the charecter buffer
iva2k 0:e614f7875b60 903 *
iva2k 0:e614f7875b60 904 * Returns : None
iva2k 0:e614f7875b60 905 *
iva2k 0:e614f7875b60 906 **************************************************************************************************************
iva2k 0:e614f7875b60 907 */
iva2k 0:e614f7875b60 908
iva2k 0:e614f7875b60 909 void WriteBE16U (volatile USB_INT08U *pmem,
iva2k 0:e614f7875b60 910 USB_INT16U val)
iva2k 0:e614f7875b60 911 {
iva2k 0:e614f7875b60 912 #ifdef __BIG_ENDIAN
iva2k 0:e614f7875b60 913 *(USB_INT16U*)pmem = val;
iva2k 0:e614f7875b60 914 #else
iva2k 0:e614f7875b60 915 *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF);
iva2k 0:e614f7875b60 916 #endif
iva2k 0:e614f7875b60 917 }
iva2k 0:e614f7875b60 918
iva2k 0:e614f7875b60 919 #ifdef __cplusplus
iva2k 0:e614f7875b60 920 }
iva2k 0:e614f7875b60 921 #endif
iva2k 0:e614f7875b60 922
iva2k 0:e614f7875b60 923 #endif