Embedded C project:18/12/2014

Dependencies:   DS1307 TextLCD mbed

Committer:
ninoderkinderen
Date:
Thu Dec 18 09:35:49 2014 +0000
Revision:
0:8d87bc453349
Programma embedded C

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ninoderkinderen 0:8d87bc453349 1
ninoderkinderen 0:8d87bc453349 2 /*
ninoderkinderen 0:8d87bc453349 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
ninoderkinderen 0:8d87bc453349 4
ninoderkinderen 0:8d87bc453349 5 Permission is hereby granted, free of charge, to any person obtaining a copy
ninoderkinderen 0:8d87bc453349 6 of this software and associated documentation files (the "Software"), to deal
ninoderkinderen 0:8d87bc453349 7 in the Software without restriction, including without limitation the rights
ninoderkinderen 0:8d87bc453349 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ninoderkinderen 0:8d87bc453349 9 copies of the Software, and to permit persons to whom the Software is
ninoderkinderen 0:8d87bc453349 10 furnished to do so, subject to the following conditions:
ninoderkinderen 0:8d87bc453349 11
ninoderkinderen 0:8d87bc453349 12 The above copyright notice and this permission notice shall be included in
ninoderkinderen 0:8d87bc453349 13 all copies or substantial portions of the Software.
ninoderkinderen 0:8d87bc453349 14
ninoderkinderen 0:8d87bc453349 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ninoderkinderen 0:8d87bc453349 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ninoderkinderen 0:8d87bc453349 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ninoderkinderen 0:8d87bc453349 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ninoderkinderen 0:8d87bc453349 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ninoderkinderen 0:8d87bc453349 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
ninoderkinderen 0:8d87bc453349 21 THE SOFTWARE.
ninoderkinderen 0:8d87bc453349 22 */
ninoderkinderen 0:8d87bc453349 23
ninoderkinderen 0:8d87bc453349 24 #include "UsbHostMgr.h"
ninoderkinderen 0:8d87bc453349 25
ninoderkinderen 0:8d87bc453349 26 #include "usb_mem.h"
ninoderkinderen 0:8d87bc453349 27
ninoderkinderen 0:8d87bc453349 28 #include "string.h" //For memcpy, memmove, memset
ninoderkinderen 0:8d87bc453349 29
ninoderkinderen 0:8d87bc453349 30 #include "netCfg.h"
ninoderkinderen 0:8d87bc453349 31 #if NET_USB
ninoderkinderen 0:8d87bc453349 32
ninoderkinderen 0:8d87bc453349 33 //#define __DEBUG
ninoderkinderen 0:8d87bc453349 34 #include "dbg/dbg.h"
ninoderkinderen 0:8d87bc453349 35
ninoderkinderen 0:8d87bc453349 36 // bits of the USB/OTG clock control register
ninoderkinderen 0:8d87bc453349 37 #define HOST_CLK_EN (1<<0)
ninoderkinderen 0:8d87bc453349 38 #define DEV_CLK_EN (1<<1)
ninoderkinderen 0:8d87bc453349 39 #define PORTSEL_CLK_EN (1<<3)
ninoderkinderen 0:8d87bc453349 40 #define AHB_CLK_EN (1<<4)
ninoderkinderen 0:8d87bc453349 41
ninoderkinderen 0:8d87bc453349 42 // bits of the USB/OTG clock status register
ninoderkinderen 0:8d87bc453349 43 #define HOST_CLK_ON (1<<0)
ninoderkinderen 0:8d87bc453349 44 #define DEV_CLK_ON (1<<1)
ninoderkinderen 0:8d87bc453349 45 #define PORTSEL_CLK_ON (1<<3)
ninoderkinderen 0:8d87bc453349 46 #define AHB_CLK_ON (1<<4)
ninoderkinderen 0:8d87bc453349 47
ninoderkinderen 0:8d87bc453349 48 // we need host clock, OTG/portsel clock and AHB clock
ninoderkinderen 0:8d87bc453349 49 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
ninoderkinderen 0:8d87bc453349 50
ninoderkinderen 0:8d87bc453349 51 static UsbHostMgr* pMgr = NULL;
ninoderkinderen 0:8d87bc453349 52
ninoderkinderen 0:8d87bc453349 53 extern "C" void sUsbIrqhandler(void) __irq
ninoderkinderen 0:8d87bc453349 54 {
ninoderkinderen 0:8d87bc453349 55 DBG("\n+Int\n");
ninoderkinderen 0:8d87bc453349 56 if(pMgr)
ninoderkinderen 0:8d87bc453349 57 pMgr->UsbIrqhandler();
ninoderkinderen 0:8d87bc453349 58 DBG("\n-Int\n");
ninoderkinderen 0:8d87bc453349 59 return;
ninoderkinderen 0:8d87bc453349 60 }
ninoderkinderen 0:8d87bc453349 61
ninoderkinderen 0:8d87bc453349 62 UsbHostMgr::UsbHostMgr() : m_lpDevices()
ninoderkinderen 0:8d87bc453349 63 {
ninoderkinderen 0:8d87bc453349 64 /*if(!pMgr)*/ //Assume singleton
ninoderkinderen 0:8d87bc453349 65 pMgr = this;
ninoderkinderen 0:8d87bc453349 66 usb_mem_init();
ninoderkinderen 0:8d87bc453349 67 memset(m_lpDevices, NULL, sizeof(UsbDevice*) * USB_HOSTMGR_MAX_DEVS);
ninoderkinderen 0:8d87bc453349 68 m_pHcca = (HCCA*) usb_get_hcca();
ninoderkinderen 0:8d87bc453349 69 memset((void*)m_pHcca, 0, 0x100);
ninoderkinderen 0:8d87bc453349 70 DBG("Host manager at %p\n", this);
ninoderkinderen 0:8d87bc453349 71 }
ninoderkinderen 0:8d87bc453349 72
ninoderkinderen 0:8d87bc453349 73 UsbHostMgr::~UsbHostMgr()
ninoderkinderen 0:8d87bc453349 74 {
ninoderkinderen 0:8d87bc453349 75 if(pMgr == this)
ninoderkinderen 0:8d87bc453349 76 pMgr = NULL;
ninoderkinderen 0:8d87bc453349 77 }
ninoderkinderen 0:8d87bc453349 78
ninoderkinderen 0:8d87bc453349 79 UsbErr UsbHostMgr::init() //Initialize host
ninoderkinderen 0:8d87bc453349 80 {
ninoderkinderen 0:8d87bc453349 81 NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */
ninoderkinderen 0:8d87bc453349 82
ninoderkinderen 0:8d87bc453349 83 LPC_SC->PCONP &= ~(1UL<<31); //Cut power
ninoderkinderen 0:8d87bc453349 84 wait(1);
ninoderkinderen 0:8d87bc453349 85
ninoderkinderen 0:8d87bc453349 86
ninoderkinderen 0:8d87bc453349 87 // turn on power for USB
ninoderkinderen 0:8d87bc453349 88 LPC_SC->PCONP |= (1UL<<31);
ninoderkinderen 0:8d87bc453349 89 // Enable USB host clock, port selection and AHB clock
ninoderkinderen 0:8d87bc453349 90 LPC_USB->USBClkCtrl |= CLOCK_MASK;
ninoderkinderen 0:8d87bc453349 91 // Wait for clocks to become available
ninoderkinderen 0:8d87bc453349 92 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
ninoderkinderen 0:8d87bc453349 93 ;
ninoderkinderen 0:8d87bc453349 94
ninoderkinderen 0:8d87bc453349 95 // it seems the bits[0:1] mean the following
ninoderkinderen 0:8d87bc453349 96 // 0: U1=device, U2=host
ninoderkinderen 0:8d87bc453349 97 // 1: U1=host, U2=host
ninoderkinderen 0:8d87bc453349 98 // 2: reserved
ninoderkinderen 0:8d87bc453349 99 // 3: U1=host, U2=device
ninoderkinderen 0:8d87bc453349 100 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
ninoderkinderen 0:8d87bc453349 101 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
ninoderkinderen 0:8d87bc453349 102 LPC_USB->OTGStCtrl |= 1;
ninoderkinderen 0:8d87bc453349 103
ninoderkinderen 0:8d87bc453349 104 // now that we've configured the ports, we can turn off the portsel clock
ninoderkinderen 0:8d87bc453349 105 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
ninoderkinderen 0:8d87bc453349 106
ninoderkinderen 0:8d87bc453349 107 // power pins are not connected on mbed, so we can skip them
ninoderkinderen 0:8d87bc453349 108 /* P1[18] = USB_UP_LED, 01 */
ninoderkinderen 0:8d87bc453349 109 /* P1[19] = /USB_PPWR, 10 */
ninoderkinderen 0:8d87bc453349 110 /* P1[22] = USB_PWRD, 10 */
ninoderkinderen 0:8d87bc453349 111 /* P1[27] = /USB_OVRCR, 10 */
ninoderkinderen 0:8d87bc453349 112 /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));
ninoderkinderen 0:8d87bc453349 113 LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080
ninoderkinderen 0:8d87bc453349 114 */
ninoderkinderen 0:8d87bc453349 115
ninoderkinderen 0:8d87bc453349 116 // configure USB D+/D- pins
ninoderkinderen 0:8d87bc453349 117 /* P0[29] = USB_D+, 01 */
ninoderkinderen 0:8d87bc453349 118 /* P0[30] = USB_D-, 01 */
ninoderkinderen 0:8d87bc453349 119 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
ninoderkinderen 0:8d87bc453349 120 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
ninoderkinderen 0:8d87bc453349 121
ninoderkinderen 0:8d87bc453349 122 DBG("Initializing Host Stack\n");
ninoderkinderen 0:8d87bc453349 123
ninoderkinderen 0:8d87bc453349 124 wait_ms(100); /* Wait 50 ms before apply reset */
ninoderkinderen 0:8d87bc453349 125 LPC_USB->HcControl = 0; /* HARDWARE RESET */
ninoderkinderen 0:8d87bc453349 126 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */
ninoderkinderen 0:8d87bc453349 127 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */
ninoderkinderen 0:8d87bc453349 128
ninoderkinderen 0:8d87bc453349 129 /* SOFTWARE RESET */
ninoderkinderen 0:8d87bc453349 130 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
ninoderkinderen 0:8d87bc453349 131 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
ninoderkinderen 0:8d87bc453349 132
ninoderkinderen 0:8d87bc453349 133 /* Put HC in operational state */
ninoderkinderen 0:8d87bc453349 134 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
ninoderkinderen 0:8d87bc453349 135 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
ninoderkinderen 0:8d87bc453349 136
ninoderkinderen 0:8d87bc453349 137 LPC_USB->HcHCCA = (uint32_t)(m_pHcca);
ninoderkinderen 0:8d87bc453349 138 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */
ninoderkinderen 0:8d87bc453349 139
ninoderkinderen 0:8d87bc453349 140
ninoderkinderen 0:8d87bc453349 141 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE |
ninoderkinderen 0:8d87bc453349 142 OR_INTR_ENABLE_WDH |
ninoderkinderen 0:8d87bc453349 143 OR_INTR_ENABLE_RHSC;
ninoderkinderen 0:8d87bc453349 144
ninoderkinderen 0:8d87bc453349 145 NVIC_SetPriority(USB_IRQn, 0); /* highest priority */
ninoderkinderen 0:8d87bc453349 146 /* Enable the USB Interrupt */
ninoderkinderen 0:8d87bc453349 147 NVIC_SetVector(USB_IRQn, (uint32_t)(sUsbIrqhandler));
ninoderkinderen 0:8d87bc453349 148 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
ninoderkinderen 0:8d87bc453349 149 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
ninoderkinderen 0:8d87bc453349 150
ninoderkinderen 0:8d87bc453349 151 /* Check for any connected devices */
ninoderkinderen 0:8d87bc453349 152 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
ninoderkinderen 0:8d87bc453349 153 {
ninoderkinderen 0:8d87bc453349 154 //Device connected
ninoderkinderen 0:8d87bc453349 155 wait(1);
ninoderkinderen 0:8d87bc453349 156 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
ninoderkinderen 0:8d87bc453349 157 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
ninoderkinderen 0:8d87bc453349 158 }
ninoderkinderen 0:8d87bc453349 159
ninoderkinderen 0:8d87bc453349 160 DBG("Enabling IRQ\n");
ninoderkinderen 0:8d87bc453349 161 NVIC_EnableIRQ(USB_IRQn);
ninoderkinderen 0:8d87bc453349 162 DBG("End of host stack initialization\n");
ninoderkinderen 0:8d87bc453349 163 return USBERR_OK;
ninoderkinderen 0:8d87bc453349 164 }
ninoderkinderen 0:8d87bc453349 165
ninoderkinderen 0:8d87bc453349 166 void UsbHostMgr::poll() //Enumerate connected devices, etc
ninoderkinderen 0:8d87bc453349 167 {
ninoderkinderen 0:8d87bc453349 168 /* Check for any connected devices */
ninoderkinderen 0:8d87bc453349 169 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
ninoderkinderen 0:8d87bc453349 170 {
ninoderkinderen 0:8d87bc453349 171 //Device connected
ninoderkinderen 0:8d87bc453349 172 wait(1);
ninoderkinderen 0:8d87bc453349 173 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
ninoderkinderen 0:8d87bc453349 174 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
ninoderkinderen 0:8d87bc453349 175 }
ninoderkinderen 0:8d87bc453349 176
ninoderkinderen 0:8d87bc453349 177 for(int i = 0; i < devicesCount(); i++)
ninoderkinderen 0:8d87bc453349 178 {
ninoderkinderen 0:8d87bc453349 179 if( (m_lpDevices[i]->m_connected)
ninoderkinderen 0:8d87bc453349 180 && !(m_lpDevices[i]->m_enumerated) )
ninoderkinderen 0:8d87bc453349 181 {
ninoderkinderen 0:8d87bc453349 182 m_lpDevices[i]->enumerate();
ninoderkinderen 0:8d87bc453349 183 return;
ninoderkinderen 0:8d87bc453349 184 }
ninoderkinderen 0:8d87bc453349 185 }
ninoderkinderen 0:8d87bc453349 186 }
ninoderkinderen 0:8d87bc453349 187
ninoderkinderen 0:8d87bc453349 188 int UsbHostMgr::devicesCount()
ninoderkinderen 0:8d87bc453349 189 {
ninoderkinderen 0:8d87bc453349 190 int i;
ninoderkinderen 0:8d87bc453349 191 for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++)
ninoderkinderen 0:8d87bc453349 192 {
ninoderkinderen 0:8d87bc453349 193 if (m_lpDevices[i] == NULL)
ninoderkinderen 0:8d87bc453349 194 break;
ninoderkinderen 0:8d87bc453349 195 }
ninoderkinderen 0:8d87bc453349 196 return i;
ninoderkinderen 0:8d87bc453349 197 }
ninoderkinderen 0:8d87bc453349 198
ninoderkinderen 0:8d87bc453349 199 UsbDevice* UsbHostMgr::getDevice(int item)
ninoderkinderen 0:8d87bc453349 200 {
ninoderkinderen 0:8d87bc453349 201 UsbDevice* pDev = m_lpDevices[item];
ninoderkinderen 0:8d87bc453349 202 if(!pDev)
ninoderkinderen 0:8d87bc453349 203 return NULL;
ninoderkinderen 0:8d87bc453349 204
ninoderkinderen 0:8d87bc453349 205 pDev->m_refs++;
ninoderkinderen 0:8d87bc453349 206 return pDev;
ninoderkinderen 0:8d87bc453349 207 }
ninoderkinderen 0:8d87bc453349 208
ninoderkinderen 0:8d87bc453349 209 void UsbHostMgr::releaseDevice(UsbDevice* pDev)
ninoderkinderen 0:8d87bc453349 210 {
ninoderkinderen 0:8d87bc453349 211 pDev->m_refs--;
ninoderkinderen 0:8d87bc453349 212 if(pDev->m_refs > 0)
ninoderkinderen 0:8d87bc453349 213 return;
ninoderkinderen 0:8d87bc453349 214 //If refs count = 0, delete
ninoderkinderen 0:8d87bc453349 215 //Find & remove from list
ninoderkinderen 0:8d87bc453349 216 int i;
ninoderkinderen 0:8d87bc453349 217 for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++)
ninoderkinderen 0:8d87bc453349 218 {
ninoderkinderen 0:8d87bc453349 219 if (m_lpDevices[i] == pDev)
ninoderkinderen 0:8d87bc453349 220 break;
ninoderkinderen 0:8d87bc453349 221 }
ninoderkinderen 0:8d87bc453349 222 if(i!=USB_HOSTMGR_MAX_DEVS)
ninoderkinderen 0:8d87bc453349 223 memmove(&m_lpDevices[i], &m_lpDevices[i+1], sizeof(UsbDevice*) * (USB_HOSTMGR_MAX_DEVS - (i + 1))); //Safer than memcpy because of overlapping mem
ninoderkinderen 0:8d87bc453349 224 m_lpDevices[USB_HOSTMGR_MAX_DEVS - 1] = NULL;
ninoderkinderen 0:8d87bc453349 225 delete pDev;
ninoderkinderen 0:8d87bc453349 226 }
ninoderkinderen 0:8d87bc453349 227
ninoderkinderen 0:8d87bc453349 228 void UsbHostMgr::UsbIrqhandler()
ninoderkinderen 0:8d87bc453349 229 {
ninoderkinderen 0:8d87bc453349 230 uint32_t int_status;
ninoderkinderen 0:8d87bc453349 231 uint32_t ie_status;
ninoderkinderen 0:8d87bc453349 232
ninoderkinderen 0:8d87bc453349 233 int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */
ninoderkinderen 0:8d87bc453349 234 ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */
ninoderkinderen 0:8d87bc453349 235
ninoderkinderen 0:8d87bc453349 236 if (!(int_status & ie_status))
ninoderkinderen 0:8d87bc453349 237 {
ninoderkinderen 0:8d87bc453349 238 return;
ninoderkinderen 0:8d87bc453349 239 }
ninoderkinderen 0:8d87bc453349 240 else
ninoderkinderen 0:8d87bc453349 241 {
ninoderkinderen 0:8d87bc453349 242 int_status = int_status & ie_status;
ninoderkinderen 0:8d87bc453349 243 if (int_status & OR_INTR_STATUS_RHSC) /* Root hub status change interrupt */
ninoderkinderen 0:8d87bc453349 244 {
ninoderkinderen 0:8d87bc453349 245 DBG("LPC_USB->HcRhPortStatus1 = %08x\n", LPC_USB->HcRhPortStatus1);
ninoderkinderen 0:8d87bc453349 246 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC)
ninoderkinderen 0:8d87bc453349 247 {
ninoderkinderen 0:8d87bc453349 248 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE)
ninoderkinderen 0:8d87bc453349 249 {
ninoderkinderen 0:8d87bc453349 250 /*
ninoderkinderen 0:8d87bc453349 251 * When DRWE is on, Connect Status Change
ninoderkinderen 0:8d87bc453349 252 * means a remote wakeup event.
ninoderkinderen 0:8d87bc453349 253 */
ninoderkinderen 0:8d87bc453349 254 //HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
ninoderkinderen 0:8d87bc453349 255 }
ninoderkinderen 0:8d87bc453349 256 else
ninoderkinderen 0:8d87bc453349 257 {
ninoderkinderen 0:8d87bc453349 258 /*
ninoderkinderen 0:8d87bc453349 259 * When DRWE is off, Connect Status Change
ninoderkinderen 0:8d87bc453349 260 * is NOT a remote wakeup event
ninoderkinderen 0:8d87bc453349 261 */
ninoderkinderen 0:8d87bc453349 262 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
ninoderkinderen 0:8d87bc453349 263 {
ninoderkinderen 0:8d87bc453349 264 //Device connected
ninoderkinderen 0:8d87bc453349 265 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
ninoderkinderen 0:8d87bc453349 266 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
ninoderkinderen 0:8d87bc453349 267 }
ninoderkinderen 0:8d87bc453349 268 else //Root device disconnected
ninoderkinderen 0:8d87bc453349 269 {
ninoderkinderen 0:8d87bc453349 270 //Device disconnected
ninoderkinderen 0:8d87bc453349 271 DBG("Device disconnected\n");
ninoderkinderen 0:8d87bc453349 272 onUsbDeviceDisconnected(0, 1);
ninoderkinderen 0:8d87bc453349 273 }
ninoderkinderen 0:8d87bc453349 274 //TODO: HUBS
ninoderkinderen 0:8d87bc453349 275 }
ninoderkinderen 0:8d87bc453349 276 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
ninoderkinderen 0:8d87bc453349 277 }
ninoderkinderen 0:8d87bc453349 278 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC)
ninoderkinderen 0:8d87bc453349 279 {
ninoderkinderen 0:8d87bc453349 280 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
ninoderkinderen 0:8d87bc453349 281 }
ninoderkinderen 0:8d87bc453349 282 }
ninoderkinderen 0:8d87bc453349 283 if (int_status & OR_INTR_STATUS_WDH) /* Writeback Done Head interrupt */
ninoderkinderen 0:8d87bc453349 284 {
ninoderkinderen 0:8d87bc453349 285 //UsbEndpoint::sOnCompletion((LPC_USB->HccaDoneHead) & 0xFE);
ninoderkinderen 0:8d87bc453349 286 if(m_pHcca->DoneHead)
ninoderkinderen 0:8d87bc453349 287 {
ninoderkinderen 0:8d87bc453349 288 UsbEndpoint::sOnCompletion(m_pHcca->DoneHead);
ninoderkinderen 0:8d87bc453349 289 m_pHcca->DoneHead = 0;
ninoderkinderen 0:8d87bc453349 290 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
ninoderkinderen 0:8d87bc453349 291 if(m_pHcca->DoneHead)
ninoderkinderen 0:8d87bc453349 292 DBG("??????????????????????????????\n\n\n");
ninoderkinderen 0:8d87bc453349 293 }
ninoderkinderen 0:8d87bc453349 294 else
ninoderkinderen 0:8d87bc453349 295 {
ninoderkinderen 0:8d87bc453349 296 //Probably an error
ninoderkinderen 0:8d87bc453349 297 int_status = LPC_USB->HcInterruptStatus;
ninoderkinderen 0:8d87bc453349 298 DBG("HcInterruptStatus = %08x\n", int_status);
ninoderkinderen 0:8d87bc453349 299 if (int_status & OR_INTR_STATUS_UE) //Unrecoverable error, disconnect devices and resume
ninoderkinderen 0:8d87bc453349 300 {
ninoderkinderen 0:8d87bc453349 301 onUsbDeviceDisconnected(0, 1);
ninoderkinderen 0:8d87bc453349 302 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_UE;
ninoderkinderen 0:8d87bc453349 303 LPC_USB->HcCommandStatus = 0x01; //Host Controller Reset
ninoderkinderen 0:8d87bc453349 304 }
ninoderkinderen 0:8d87bc453349 305 }
ninoderkinderen 0:8d87bc453349 306 }
ninoderkinderen 0:8d87bc453349 307 LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */
ninoderkinderen 0:8d87bc453349 308 }
ninoderkinderen 0:8d87bc453349 309 return;
ninoderkinderen 0:8d87bc453349 310 }
ninoderkinderen 0:8d87bc453349 311
ninoderkinderen 0:8d87bc453349 312 void UsbHostMgr::onUsbDeviceConnected(int hub, int port)
ninoderkinderen 0:8d87bc453349 313 {
ninoderkinderen 0:8d87bc453349 314 int item = devicesCount();
ninoderkinderen 0:8d87bc453349 315 if( item == USB_HOSTMGR_MAX_DEVS )
ninoderkinderen 0:8d87bc453349 316 return; //List full...
ninoderkinderen 0:8d87bc453349 317 //Find a free address (not optimized, but not really important)
ninoderkinderen 0:8d87bc453349 318 int i;
ninoderkinderen 0:8d87bc453349 319 int addr = 1;
ninoderkinderen 0:8d87bc453349 320 for(i = 0; i < item; i++)
ninoderkinderen 0:8d87bc453349 321 {
ninoderkinderen 0:8d87bc453349 322 addr = MAX( addr, m_lpDevices[i]->m_addr + 1 );
ninoderkinderen 0:8d87bc453349 323 }
ninoderkinderen 0:8d87bc453349 324 m_lpDevices[item] = new UsbDevice( this, hub, port, addr );
ninoderkinderen 0:8d87bc453349 325 m_lpDevices[item]->m_connected = true;
ninoderkinderen 0:8d87bc453349 326 }
ninoderkinderen 0:8d87bc453349 327
ninoderkinderen 0:8d87bc453349 328 void UsbHostMgr::onUsbDeviceDisconnected(int hub, int port)
ninoderkinderen 0:8d87bc453349 329 {
ninoderkinderen 0:8d87bc453349 330 for(int i = 0; i < devicesCount(); i++)
ninoderkinderen 0:8d87bc453349 331 {
ninoderkinderen 0:8d87bc453349 332 if( (m_lpDevices[i]->m_hub == hub)
ninoderkinderen 0:8d87bc453349 333 && (m_lpDevices[i]->m_port == port) )
ninoderkinderen 0:8d87bc453349 334 {
ninoderkinderen 0:8d87bc453349 335 m_lpDevices[i]->m_connected = false;
ninoderkinderen 0:8d87bc453349 336 if(!m_lpDevices[i]->m_enumerated)
ninoderkinderen 0:8d87bc453349 337 {
ninoderkinderen 0:8d87bc453349 338 delete m_lpDevices[i];
ninoderkinderen 0:8d87bc453349 339 m_lpDevices[i] = NULL;
ninoderkinderen 0:8d87bc453349 340 }
ninoderkinderen 0:8d87bc453349 341 return;
ninoderkinderen 0:8d87bc453349 342 }
ninoderkinderen 0:8d87bc453349 343 }
ninoderkinderen 0:8d87bc453349 344 }
ninoderkinderen 0:8d87bc453349 345
ninoderkinderen 0:8d87bc453349 346 void UsbHostMgr::resetPort(int hub, int port)
ninoderkinderen 0:8d87bc453349 347 {
ninoderkinderen 0:8d87bc453349 348 DBG("Resetting hub %d, port %d\n", hub, port);
ninoderkinderen 0:8d87bc453349 349 if(hub == 0) //Root hub
ninoderkinderen 0:8d87bc453349 350 {
ninoderkinderen 0:8d87bc453349 351 wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */
ninoderkinderen 0:8d87bc453349 352 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
ninoderkinderen 0:8d87bc453349 353 DBG("Before loop\n");
ninoderkinderen 0:8d87bc453349 354 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
ninoderkinderen 0:8d87bc453349 355 ;
ninoderkinderen 0:8d87bc453349 356 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
ninoderkinderen 0:8d87bc453349 357 DBG("After loop\n");
ninoderkinderen 0:8d87bc453349 358 wait_ms(200); /* Wait for 100 MS after port reset */
ninoderkinderen 0:8d87bc453349 359 }
ninoderkinderen 0:8d87bc453349 360 else
ninoderkinderen 0:8d87bc453349 361 {
ninoderkinderen 0:8d87bc453349 362 //TODO: Hubs
ninoderkinderen 0:8d87bc453349 363 }
ninoderkinderen 0:8d87bc453349 364 DBG("Port reset OK\n");
ninoderkinderen 0:8d87bc453349 365 }
ninoderkinderen 0:8d87bc453349 366
ninoderkinderen 0:8d87bc453349 367 #endif