Junichi Katsu / Mbed 2 deprecated BLEControl

Dependencies:   FatFileSystem TB6612FNG2 mbed

Committer:
mbed_Cookbook_SE
Date:
Mon Nov 30 09:32:15 2015 +0000
Revision:
0:de03cbbcd0ff
??

Who changed what in which revision?

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