Example self-announcing webserver which controls a servo through a smallHTML userinterface.

Dependencies:   mbed

Committer:
dirkx
Date:
Sat Aug 14 15:56:01 2010 +0000
Revision:
0:a259777c45a3

        

Who changed what in which revision?

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