SNMP agent attached to SPI slave

Dependencies:   mbed

Committer:
lorcansmith
Date:
Mon Aug 13 15:07:40 2012 +0000
Revision:
0:2a53a4c3238c
v1.1 release includes ioAlarm traps

Who changed what in which revision?

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