Integrating the ublox LISA C200 modem

Fork of SprintUSBModemHTTPClientTest by Donatien Garnier

Committer:
sam_grove
Date:
Tue Oct 08 00:08:22 2013 +0000
Revision:
21:3f45e53afe4f
Parent:
5:3f93dd1d4cb3
Added http client test. Return from post seems to be a bit wonky but haven't looked closely at this

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 5:3f93dd1d4cb3 1 /* Copyright (c) 2010-2012 mbed.org, MIT License
sam_grove 5:3f93dd1d4cb3 2 *
sam_grove 5:3f93dd1d4cb3 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
sam_grove 5:3f93dd1d4cb3 4 * and associated documentation files (the "Software"), to deal in the Software without
sam_grove 5:3f93dd1d4cb3 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
sam_grove 5:3f93dd1d4cb3 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
sam_grove 5:3f93dd1d4cb3 7 * Software is furnished to do so, subject to the following conditions:
sam_grove 5:3f93dd1d4cb3 8 *
sam_grove 5:3f93dd1d4cb3 9 * The above copyright notice and this permission notice shall be included in all copies or
sam_grove 5:3f93dd1d4cb3 10 * substantial portions of the Software.
sam_grove 5:3f93dd1d4cb3 11 *
sam_grove 5:3f93dd1d4cb3 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
sam_grove 5:3f93dd1d4cb3 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
sam_grove 5:3f93dd1d4cb3 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
sam_grove 5:3f93dd1d4cb3 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
sam_grove 5:3f93dd1d4cb3 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
sam_grove 5:3f93dd1d4cb3 17 */
sam_grove 5:3f93dd1d4cb3 18
sam_grove 5:3f93dd1d4cb3 19 #define __DEBUG__ 0 //WARN: ENABLING DEBUGGING HERE WILL PRINTF IN IRQS!! UNEXPECTED BEHAVIOUR MAY RESULT...
sam_grove 5:3f93dd1d4cb3 20 #ifndef __MODULE__
sam_grove 5:3f93dd1d4cb3 21 #define __MODULE__ "USBHALHost.cpp"
sam_grove 5:3f93dd1d4cb3 22 #endif
sam_grove 5:3f93dd1d4cb3 23
sam_grove 5:3f93dd1d4cb3 24 #include "core/dbg.h"
sam_grove 5:3f93dd1d4cb3 25 #include <cstdint>
sam_grove 5:3f93dd1d4cb3 26
sam_grove 5:3f93dd1d4cb3 27 #include "mbed.h"
sam_grove 5:3f93dd1d4cb3 28 #include "USBHALHost.h"
sam_grove 5:3f93dd1d4cb3 29
sam_grove 5:3f93dd1d4cb3 30 // bits of the USB/OTG clock control register
sam_grove 5:3f93dd1d4cb3 31 #define HOST_CLK_EN (1<<0)
sam_grove 5:3f93dd1d4cb3 32 #define DEV_CLK_EN (1<<1)
sam_grove 5:3f93dd1d4cb3 33 #define PORTSEL_CLK_EN (1<<3)
sam_grove 5:3f93dd1d4cb3 34 #define AHB_CLK_EN (1<<4)
sam_grove 5:3f93dd1d4cb3 35
sam_grove 5:3f93dd1d4cb3 36 // bits of the USB/OTG clock status register
sam_grove 5:3f93dd1d4cb3 37 #define HOST_CLK_ON (1<<0)
sam_grove 5:3f93dd1d4cb3 38 #define DEV_CLK_ON (1<<1)
sam_grove 5:3f93dd1d4cb3 39 #define PORTSEL_CLK_ON (1<<3)
sam_grove 5:3f93dd1d4cb3 40 #define AHB_CLK_ON (1<<4)
sam_grove 5:3f93dd1d4cb3 41
sam_grove 5:3f93dd1d4cb3 42 // we need host clock, OTG/portsel clock and AHB clock
sam_grove 5:3f93dd1d4cb3 43 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
sam_grove 5:3f93dd1d4cb3 44
sam_grove 5:3f93dd1d4cb3 45
sam_grove 5:3f93dd1d4cb3 46
sam_grove 5:3f93dd1d4cb3 47 #define HCCA_SIZE 0x100
sam_grove 5:3f93dd1d4cb3 48 #define ED_SIZE 0x10
sam_grove 5:3f93dd1d4cb3 49 #define TD_SIZE 0x10
sam_grove 5:3f93dd1d4cb3 50
sam_grove 5:3f93dd1d4cb3 51 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
sam_grove 5:3f93dd1d4cb3 52
sam_grove 5:3f93dd1d4cb3 53 static volatile __align(256) uint8_t usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM1"),aligned)); //256 bytes aligned!
sam_grove 5:3f93dd1d4cb3 54
sam_grove 5:3f93dd1d4cb3 55 USBHALHost * USBHALHost::instHost;
sam_grove 5:3f93dd1d4cb3 56
sam_grove 5:3f93dd1d4cb3 57 USBHALHost::USBHALHost() : thread(USBHALHost::staticCb, (void*)this, osPriorityNormal, /*4*128*/4*192) {
sam_grove 5:3f93dd1d4cb3 58 instHost = this;
sam_grove 5:3f93dd1d4cb3 59 memInit();
sam_grove 5:3f93dd1d4cb3 60 memset((void*)usb_hcca, 0, HCCA_SIZE);
sam_grove 5:3f93dd1d4cb3 61 for (int i = 0; i < MAX_ENDPOINT; i++) {
sam_grove 5:3f93dd1d4cb3 62 edBufAlloc[i] = false;
sam_grove 5:3f93dd1d4cb3 63 }
sam_grove 5:3f93dd1d4cb3 64 for (int i = 0; i < MAX_TD; i++) {
sam_grove 5:3f93dd1d4cb3 65 tdBufAlloc[i] = false;
sam_grove 5:3f93dd1d4cb3 66 }
sam_grove 5:3f93dd1d4cb3 67 }
sam_grove 5:3f93dd1d4cb3 68
sam_grove 5:3f93dd1d4cb3 69
sam_grove 5:3f93dd1d4cb3 70 void USBHALHost::init() {
sam_grove 5:3f93dd1d4cb3 71 thread.signal_set(USBHALHOST_SIG_INIT);
sam_grove 5:3f93dd1d4cb3 72 }
sam_grove 5:3f93dd1d4cb3 73
sam_grove 5:3f93dd1d4cb3 74
sam_grove 5:3f93dd1d4cb3 75 uint32_t USBHALHost::controlHeadED() {
sam_grove 5:3f93dd1d4cb3 76 return LPC_USB->HcControlHeadED;
sam_grove 5:3f93dd1d4cb3 77 }
sam_grove 5:3f93dd1d4cb3 78
sam_grove 5:3f93dd1d4cb3 79 uint32_t USBHALHost::bulkHeadED() {
sam_grove 5:3f93dd1d4cb3 80 return LPC_USB->HcBulkHeadED;
sam_grove 5:3f93dd1d4cb3 81 }
sam_grove 5:3f93dd1d4cb3 82
sam_grove 5:3f93dd1d4cb3 83 uint32_t USBHALHost::interruptHeadED() {
sam_grove 5:3f93dd1d4cb3 84 return usb_hcca->IntTable[0];
sam_grove 5:3f93dd1d4cb3 85 }
sam_grove 5:3f93dd1d4cb3 86
sam_grove 5:3f93dd1d4cb3 87 void USBHALHost::updateBulkHeadED(uint32_t addr) {
sam_grove 5:3f93dd1d4cb3 88 LPC_USB->HcBulkHeadED = addr;
sam_grove 5:3f93dd1d4cb3 89 }
sam_grove 5:3f93dd1d4cb3 90
sam_grove 5:3f93dd1d4cb3 91
sam_grove 5:3f93dd1d4cb3 92 void USBHALHost::updateControlHeadED(uint32_t addr) {
sam_grove 5:3f93dd1d4cb3 93 LPC_USB->HcControlHeadED = addr;
sam_grove 5:3f93dd1d4cb3 94 }
sam_grove 5:3f93dd1d4cb3 95
sam_grove 5:3f93dd1d4cb3 96 void USBHALHost::updateInterruptHeadED(uint32_t addr) {
sam_grove 5:3f93dd1d4cb3 97 usb_hcca->IntTable[0] = addr;
sam_grove 5:3f93dd1d4cb3 98 }
sam_grove 5:3f93dd1d4cb3 99
sam_grove 5:3f93dd1d4cb3 100
sam_grove 5:3f93dd1d4cb3 101 void USBHALHost::enableControlList() {
sam_grove 5:3f93dd1d4cb3 102 LPC_USB->HcCommandStatus = OR_CMD_STATUS_CLF;
sam_grove 5:3f93dd1d4cb3 103 LPC_USB->HcControl |= OR_CONTROL_CLE; //Enable control list
sam_grove 5:3f93dd1d4cb3 104 }
sam_grove 5:3f93dd1d4cb3 105
sam_grove 5:3f93dd1d4cb3 106 void USBHALHost::enableBulkList() {
sam_grove 5:3f93dd1d4cb3 107 LPC_USB->HcCommandStatus = OR_CMD_STATUS_BLF;
sam_grove 5:3f93dd1d4cb3 108 LPC_USB->HcControl |= OR_CONTROL_BLE; //Enable bulk list
sam_grove 5:3f93dd1d4cb3 109 }
sam_grove 5:3f93dd1d4cb3 110
sam_grove 5:3f93dd1d4cb3 111 void USBHALHost::enableInterruptList() {
sam_grove 5:3f93dd1d4cb3 112 LPC_USB->HcControl |= OR_CONTROL_PLE;
sam_grove 5:3f93dd1d4cb3 113 }
sam_grove 5:3f93dd1d4cb3 114
sam_grove 5:3f93dd1d4cb3 115 bool USBHALHost::disableControlList() {
sam_grove 5:3f93dd1d4cb3 116 if(LPC_USB->HcControl & OR_CONTROL_CLE)
sam_grove 5:3f93dd1d4cb3 117 {
sam_grove 5:3f93dd1d4cb3 118 LPC_USB->HcControl &= ~OR_CONTROL_CLE; //Disable control list
sam_grove 5:3f93dd1d4cb3 119 return true;
sam_grove 5:3f93dd1d4cb3 120 }
sam_grove 5:3f93dd1d4cb3 121 else
sam_grove 5:3f93dd1d4cb3 122 {
sam_grove 5:3f93dd1d4cb3 123 return false;
sam_grove 5:3f93dd1d4cb3 124 }
sam_grove 5:3f93dd1d4cb3 125 }
sam_grove 5:3f93dd1d4cb3 126
sam_grove 5:3f93dd1d4cb3 127 bool USBHALHost::disableBulkList() {
sam_grove 5:3f93dd1d4cb3 128 if(LPC_USB->HcControl & OR_CONTROL_BLE)
sam_grove 5:3f93dd1d4cb3 129 {
sam_grove 5:3f93dd1d4cb3 130 LPC_USB->HcControl &= ~OR_CONTROL_BLE; //Disable bulk list
sam_grove 5:3f93dd1d4cb3 131 return true;
sam_grove 5:3f93dd1d4cb3 132 }
sam_grove 5:3f93dd1d4cb3 133 else
sam_grove 5:3f93dd1d4cb3 134 {
sam_grove 5:3f93dd1d4cb3 135 return false;
sam_grove 5:3f93dd1d4cb3 136 }
sam_grove 5:3f93dd1d4cb3 137 }
sam_grove 5:3f93dd1d4cb3 138
sam_grove 5:3f93dd1d4cb3 139 bool USBHALHost::disableInterruptList() {
sam_grove 5:3f93dd1d4cb3 140 if(LPC_USB->HcControl & OR_CONTROL_PLE)
sam_grove 5:3f93dd1d4cb3 141 {
sam_grove 5:3f93dd1d4cb3 142 LPC_USB->HcControl &= ~OR_CONTROL_PLE; //Disable interrupt list
sam_grove 5:3f93dd1d4cb3 143 return true;
sam_grove 5:3f93dd1d4cb3 144 }
sam_grove 5:3f93dd1d4cb3 145 else
sam_grove 5:3f93dd1d4cb3 146 {
sam_grove 5:3f93dd1d4cb3 147 return false;
sam_grove 5:3f93dd1d4cb3 148 }
sam_grove 5:3f93dd1d4cb3 149 }
sam_grove 5:3f93dd1d4cb3 150
sam_grove 5:3f93dd1d4cb3 151 //Lock processing
sam_grove 5:3f93dd1d4cb3 152 void USBHALHost::lock()
sam_grove 5:3f93dd1d4cb3 153 {
sam_grove 5:3f93dd1d4cb3 154 mtx.lock();
sam_grove 5:3f93dd1d4cb3 155 }
sam_grove 5:3f93dd1d4cb3 156
sam_grove 5:3f93dd1d4cb3 157 void USBHALHost::unlock()
sam_grove 5:3f93dd1d4cb3 158 {
sam_grove 5:3f93dd1d4cb3 159 mtx.unlock();
sam_grove 5:3f93dd1d4cb3 160 }
sam_grove 5:3f93dd1d4cb3 161
sam_grove 5:3f93dd1d4cb3 162 void USBHALHost::memInit() {
sam_grove 5:3f93dd1d4cb3 163 usb_hcca = (volatile HCCA *)usb_buf;
sam_grove 5:3f93dd1d4cb3 164 usb_edBuf = usb_buf + HCCA_SIZE;
sam_grove 5:3f93dd1d4cb3 165 usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE);
sam_grove 5:3f93dd1d4cb3 166 }
sam_grove 5:3f93dd1d4cb3 167
sam_grove 5:3f93dd1d4cb3 168 volatile uint8_t * USBHALHost::getED() {
sam_grove 5:3f93dd1d4cb3 169 for (int i = 0; i < MAX_ENDPOINT; i++) {
sam_grove 5:3f93dd1d4cb3 170 if ( !edBufAlloc[i] ) {
sam_grove 5:3f93dd1d4cb3 171 edBufAlloc[i] = true;
sam_grove 5:3f93dd1d4cb3 172 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
sam_grove 5:3f93dd1d4cb3 173 }
sam_grove 5:3f93dd1d4cb3 174 }
sam_grove 5:3f93dd1d4cb3 175 perror("Could not allocate ED\r\n");
sam_grove 5:3f93dd1d4cb3 176 return NULL; //Could not alloc ED
sam_grove 5:3f93dd1d4cb3 177 }
sam_grove 5:3f93dd1d4cb3 178
sam_grove 5:3f93dd1d4cb3 179 volatile uint8_t * USBHALHost::getTD() {
sam_grove 5:3f93dd1d4cb3 180 int i;
sam_grove 5:3f93dd1d4cb3 181 for (i = 0; i < MAX_TD; i++) {
sam_grove 5:3f93dd1d4cb3 182 if ( !tdBufAlloc[i] ) {
sam_grove 5:3f93dd1d4cb3 183 tdBufAlloc[i] = true;
sam_grove 5:3f93dd1d4cb3 184 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
sam_grove 5:3f93dd1d4cb3 185 }
sam_grove 5:3f93dd1d4cb3 186 }
sam_grove 5:3f93dd1d4cb3 187 perror("Could not allocate TD\r\n");
sam_grove 5:3f93dd1d4cb3 188 return NULL; //Could not alloc TD
sam_grove 5:3f93dd1d4cb3 189 }
sam_grove 5:3f93dd1d4cb3 190
sam_grove 5:3f93dd1d4cb3 191
sam_grove 5:3f93dd1d4cb3 192 void USBHALHost::freeED(volatile uint8_t * ed) {
sam_grove 5:3f93dd1d4cb3 193 int i;
sam_grove 5:3f93dd1d4cb3 194 i = (ed - usb_edBuf) / ED_SIZE;
sam_grove 5:3f93dd1d4cb3 195 edBufAlloc[i] = false;
sam_grove 5:3f93dd1d4cb3 196 }
sam_grove 5:3f93dd1d4cb3 197
sam_grove 5:3f93dd1d4cb3 198 void USBHALHost::freeTD(volatile uint8_t * td) {
sam_grove 5:3f93dd1d4cb3 199 int i;
sam_grove 5:3f93dd1d4cb3 200 i = (td - usb_tdBuf) / TD_SIZE;
sam_grove 5:3f93dd1d4cb3 201 tdBufAlloc[i] = false;
sam_grove 5:3f93dd1d4cb3 202 }
sam_grove 5:3f93dd1d4cb3 203
sam_grove 5:3f93dd1d4cb3 204
sam_grove 5:3f93dd1d4cb3 205 void USBHALHost::resetPort(int hub, int port) {
sam_grove 5:3f93dd1d4cb3 206 DBG("Resetting hub %d, port %d\n", hub, port);
sam_grove 5:3f93dd1d4cb3 207 if (hub == 0) { //Root hub
sam_grove 5:3f93dd1d4cb3 208 // USB 2.0 spec says at least 50ms delay before port reset
sam_grove 5:3f93dd1d4cb3 209 Thread::wait(200);
sam_grove 5:3f93dd1d4cb3 210 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
sam_grove 5:3f93dd1d4cb3 211 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
sam_grove 5:3f93dd1d4cb3 212 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
sam_grove 5:3f93dd1d4cb3 213 // Wait for 100 MS after port reset
sam_grove 5:3f93dd1d4cb3 214 Thread::wait(200);
sam_grove 5:3f93dd1d4cb3 215 } else {
sam_grove 5:3f93dd1d4cb3 216 //TODO: Hubs
sam_grove 5:3f93dd1d4cb3 217 }
sam_grove 5:3f93dd1d4cb3 218 }
sam_grove 5:3f93dd1d4cb3 219
sam_grove 5:3f93dd1d4cb3 220
sam_grove 5:3f93dd1d4cb3 221 void USBHALHost::_usbisr(void) {
sam_grove 5:3f93dd1d4cb3 222 if (instHost) {
sam_grove 5:3f93dd1d4cb3 223 instHost->UsbIrqhandler();
sam_grove 5:3f93dd1d4cb3 224 }
sam_grove 5:3f93dd1d4cb3 225 }
sam_grove 5:3f93dd1d4cb3 226
sam_grove 5:3f93dd1d4cb3 227 void USBHALHost::UsbIrqhandler() {
sam_grove 5:3f93dd1d4cb3 228 if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
sam_grove 5:3f93dd1d4cb3 229 {
sam_grove 5:3f93dd1d4cb3 230 NVIC_DisableIRQ(USB_IRQn);
sam_grove 5:3f93dd1d4cb3 231 NVIC_ClearPendingIRQ(USB_IRQn);
sam_grove 5:3f93dd1d4cb3 232 thread.signal_set(USBHALHOST_SIG_IRQ); //Signal processing thread
sam_grove 5:3f93dd1d4cb3 233 }
sam_grove 5:3f93dd1d4cb3 234
sam_grove 5:3f93dd1d4cb3 235 }
sam_grove 5:3f93dd1d4cb3 236
sam_grove 5:3f93dd1d4cb3 237 void USBHALHost::process()
sam_grove 5:3f93dd1d4cb3 238 {
sam_grove 5:3f93dd1d4cb3 239 DBG("USB Process started");
sam_grove 5:3f93dd1d4cb3 240
sam_grove 5:3f93dd1d4cb3 241 lock();
sam_grove 5:3f93dd1d4cb3 242 Thread::signal_wait(USBHALHOST_SIG_INIT);
sam_grove 5:3f93dd1d4cb3 243
sam_grove 5:3f93dd1d4cb3 244 NVIC_DisableIRQ(USB_IRQn); // Disable the USB interrupt source
sam_grove 5:3f93dd1d4cb3 245
sam_grove 5:3f93dd1d4cb3 246 LPC_SC->PCONP &= ~(1UL<<31); //Cut power
sam_grove 5:3f93dd1d4cb3 247 Thread::wait(200);
sam_grove 5:3f93dd1d4cb3 248
sam_grove 5:3f93dd1d4cb3 249 // turn on power for USB
sam_grove 5:3f93dd1d4cb3 250 LPC_SC->PCONP |= (1UL<<31);
sam_grove 5:3f93dd1d4cb3 251
sam_grove 5:3f93dd1d4cb3 252 // Enable USB host clock, port selection and AHB clock
sam_grove 5:3f93dd1d4cb3 253 LPC_USB->USBClkCtrl |= CLOCK_MASK;
sam_grove 5:3f93dd1d4cb3 254
sam_grove 5:3f93dd1d4cb3 255 // Wait for clocks to become available
sam_grove 5:3f93dd1d4cb3 256 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK);
sam_grove 5:3f93dd1d4cb3 257
sam_grove 5:3f93dd1d4cb3 258 // it seems the bits[0:1] mean the following
sam_grove 5:3f93dd1d4cb3 259 // 0: U1=device, U2=host
sam_grove 5:3f93dd1d4cb3 260 // 1: U1=host, U2=host
sam_grove 5:3f93dd1d4cb3 261 // 2: reserved
sam_grove 5:3f93dd1d4cb3 262 // 3: U1=host, U2=device
sam_grove 5:3f93dd1d4cb3 263 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
sam_grove 5:3f93dd1d4cb3 264 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
sam_grove 5:3f93dd1d4cb3 265 LPC_USB->OTGStCtrl |= 1;
sam_grove 5:3f93dd1d4cb3 266
sam_grove 5:3f93dd1d4cb3 267 // now that we've configured the ports, we can turn off the portsel clock
sam_grove 5:3f93dd1d4cb3 268 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
sam_grove 5:3f93dd1d4cb3 269
sam_grove 5:3f93dd1d4cb3 270 // configure USB D+/D- pins
sam_grove 5:3f93dd1d4cb3 271 // P0[29] = USB_D+, 01
sam_grove 5:3f93dd1d4cb3 272 // P0[30] = USB_D-, 01
sam_grove 5:3f93dd1d4cb3 273 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
sam_grove 5:3f93dd1d4cb3 274 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
sam_grove 5:3f93dd1d4cb3 275
sam_grove 5:3f93dd1d4cb3 276 LPC_USB->HcControl = 0; // HARDWARE RESET
sam_grove 5:3f93dd1d4cb3 277 LPC_USB->HcControlHeadED = 0; // Initialize Control list head to Zero
sam_grove 5:3f93dd1d4cb3 278 LPC_USB->HcBulkHeadED = 0; // Initialize Bulk list head to Zero
sam_grove 5:3f93dd1d4cb3 279
sam_grove 5:3f93dd1d4cb3 280 //wait_ms(100); // Wait 50 ms before apply reset
sam_grove 5:3f93dd1d4cb3 281 Thread::wait(100);
sam_grove 5:3f93dd1d4cb3 282
sam_grove 5:3f93dd1d4cb3 283 // SOFTWARE RESET
sam_grove 5:3f93dd1d4cb3 284 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
sam_grove 5:3f93dd1d4cb3 285 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; // Write Fm Interval and Largest Data Packet Counter
sam_grove 5:3f93dd1d4cb3 286 LPC_USB->HcPeriodicStart = FI * 90 / 100;
sam_grove 5:3f93dd1d4cb3 287
sam_grove 5:3f93dd1d4cb3 288 // Put HC in operational state
sam_grove 5:3f93dd1d4cb3 289 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
sam_grove 5:3f93dd1d4cb3 290 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; // Set Global Power
sam_grove 5:3f93dd1d4cb3 291
sam_grove 5:3f93dd1d4cb3 292 LPC_USB->HcHCCA = (uint32_t)(usb_hcca);
sam_grove 5:3f93dd1d4cb3 293 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; // Clear Interrrupt Status
sam_grove 5:3f93dd1d4cb3 294
sam_grove 5:3f93dd1d4cb3 295 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC;
sam_grove 5:3f93dd1d4cb3 296
sam_grove 5:3f93dd1d4cb3 297 //DG: Do not set prio
sam_grove 5:3f93dd1d4cb3 298 //NVIC_SetPriority(USB_IRQn, 0); // highest priority
sam_grove 5:3f93dd1d4cb3 299 // Enable the USB Interrupt
sam_grove 5:3f93dd1d4cb3 300 NVIC_SetVector(USB_IRQn, (uint32_t)(_usbisr));
sam_grove 5:3f93dd1d4cb3 301 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
sam_grove 5:3f93dd1d4cb3 302 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
sam_grove 5:3f93dd1d4cb3 303
sam_grove 5:3f93dd1d4cb3 304 NVIC_EnableIRQ(USB_IRQn);
sam_grove 5:3f93dd1d4cb3 305
sam_grove 5:3f93dd1d4cb3 306
sam_grove 5:3f93dd1d4cb3 307 // Check for any connected devices
sam_grove 5:3f93dd1d4cb3 308 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) { //Root device connected
sam_grove 5:3f93dd1d4cb3 309 //Device connected
sam_grove 5:3f93dd1d4cb3 310 Thread::wait(500);
sam_grove 5:3f93dd1d4cb3 311 DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus1);
sam_grove 5:3f93dd1d4cb3 312 deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA); //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
sam_grove 5:3f93dd1d4cb3 313 }
sam_grove 5:3f93dd1d4cb3 314
sam_grove 5:3f93dd1d4cb3 315 unlock();
sam_grove 5:3f93dd1d4cb3 316
sam_grove 5:3f93dd1d4cb3 317
sam_grove 5:3f93dd1d4cb3 318 for(;;)
sam_grove 5:3f93dd1d4cb3 319 {
sam_grove 5:3f93dd1d4cb3 320 Thread::signal_wait(USBHALHOST_SIG_IRQ); //Wait for IRQ to process
sam_grove 5:3f93dd1d4cb3 321
sam_grove 5:3f93dd1d4cb3 322 lock();
sam_grove 5:3f93dd1d4cb3 323 DBG("Locked");
sam_grove 5:3f93dd1d4cb3 324
sam_grove 5:3f93dd1d4cb3 325 WARN("isr %08x [EN %08x]", LPC_USB->HcInterruptStatus, LPC_USB->HcInterruptEnable);
sam_grove 5:3f93dd1d4cb3 326
sam_grove 5:3f93dd1d4cb3 327 //Now process IRQ
sam_grove 5:3f93dd1d4cb3 328 uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
sam_grove 5:3f93dd1d4cb3 329
sam_grove 5:3f93dd1d4cb3 330 if (int_status & OR_INTR_STATUS_RHSC)
sam_grove 5:3f93dd1d4cb3 331 { // Root hub status change interrupt
sam_grove 5:3f93dd1d4cb3 332 WARN("Port status %08x", LPC_USB->HcRhPortStatus1);
sam_grove 5:3f93dd1d4cb3 333 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC)
sam_grove 5:3f93dd1d4cb3 334 {
sam_grove 5:3f93dd1d4cb3 335 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE)
sam_grove 5:3f93dd1d4cb3 336 {
sam_grove 5:3f93dd1d4cb3 337
sam_grove 5:3f93dd1d4cb3 338 // When DRWE is on, Connect Status Change
sam_grove 5:3f93dd1d4cb3 339 // means a remote wakeup event.
sam_grove 5:3f93dd1d4cb3 340 WARN("WUP");
sam_grove 5:3f93dd1d4cb3 341 }
sam_grove 5:3f93dd1d4cb3 342 else
sam_grove 5:3f93dd1d4cb3 343 {
sam_grove 5:3f93dd1d4cb3 344
sam_grove 5:3f93dd1d4cb3 345 // When DRWE is off, Connect Status Change
sam_grove 5:3f93dd1d4cb3 346 // is NOT a remote wakeup event
sam_grove 5:3f93dd1d4cb3 347
sam_grove 5:3f93dd1d4cb3 348 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS)
sam_grove 5:3f93dd1d4cb3 349 { //Root device connected
sam_grove 5:3f93dd1d4cb3 350 //Device connected
sam_grove 5:3f93dd1d4cb3 351 WARN("Device connected!!");
sam_grove 5:3f93dd1d4cb3 352 Thread::wait(2000);
sam_grove 5:3f93dd1d4cb3 353 deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA); //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
sam_grove 5:3f93dd1d4cb3 354 }
sam_grove 5:3f93dd1d4cb3 355 else
sam_grove 5:3f93dd1d4cb3 356 { //Root device disconnected
sam_grove 5:3f93dd1d4cb3 357 //Device disconnected
sam_grove 5:3f93dd1d4cb3 358 WARN("Device disconnected!!");
sam_grove 5:3f93dd1d4cb3 359 //Thread::wait(2000);
sam_grove 5:3f93dd1d4cb3 360 if (!(int_status & OR_INTR_STATUS_WDH))
sam_grove 5:3f93dd1d4cb3 361 {
sam_grove 5:3f93dd1d4cb3 362 usb_hcca->DoneHead = 0;
sam_grove 5:3f93dd1d4cb3 363 }
sam_grove 5:3f93dd1d4cb3 364 deviceDisconnected(0, 1, usb_hcca->DoneHead & 0xFFFFFFFE);
sam_grove 5:3f93dd1d4cb3 365 if (int_status & OR_INTR_STATUS_WDH)
sam_grove 5:3f93dd1d4cb3 366 {
sam_grove 5:3f93dd1d4cb3 367 usb_hcca->DoneHead = 0;
sam_grove 5:3f93dd1d4cb3 368 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
sam_grove 5:3f93dd1d4cb3 369 }
sam_grove 5:3f93dd1d4cb3 370 }
sam_grove 5:3f93dd1d4cb3 371 //TODO: HUBS
sam_grove 5:3f93dd1d4cb3 372 }
sam_grove 5:3f93dd1d4cb3 373 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
sam_grove 5:3f93dd1d4cb3 374 }
sam_grove 5:3f93dd1d4cb3 375 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC)
sam_grove 5:3f93dd1d4cb3 376 {
sam_grove 5:3f93dd1d4cb3 377 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
sam_grove 5:3f93dd1d4cb3 378 //int_status &= ~OR_RH_PORT_PRSC;
sam_grove 5:3f93dd1d4cb3 379 }
sam_grove 5:3f93dd1d4cb3 380 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_RHSC;
sam_grove 5:3f93dd1d4cb3 381 }
sam_grove 5:3f93dd1d4cb3 382
sam_grove 5:3f93dd1d4cb3 383 if (int_status & OR_INTR_STATUS_WDH)
sam_grove 5:3f93dd1d4cb3 384 { // Writeback Done Head interrupt
sam_grove 5:3f93dd1d4cb3 385 transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
sam_grove 5:3f93dd1d4cb3 386 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
sam_grove 5:3f93dd1d4cb3 387 }
sam_grove 5:3f93dd1d4cb3 388
sam_grove 5:3f93dd1d4cb3 389 //IRQ Processed
sam_grove 5:3f93dd1d4cb3 390
sam_grove 5:3f93dd1d4cb3 391 DBG("Unlocked");
sam_grove 5:3f93dd1d4cb3 392
sam_grove 5:3f93dd1d4cb3 393 NVIC_EnableIRQ(USB_IRQn);
sam_grove 5:3f93dd1d4cb3 394
sam_grove 5:3f93dd1d4cb3 395 unlock();
sam_grove 5:3f93dd1d4cb3 396
sam_grove 5:3f93dd1d4cb3 397 }
sam_grove 5:3f93dd1d4cb3 398 }
sam_grove 5:3f93dd1d4cb3 399
sam_grove 5:3f93dd1d4cb3 400 /*static*/ void USBHALHost::staticCb(void const* p)
sam_grove 5:3f93dd1d4cb3 401 {
sam_grove 5:3f93dd1d4cb3 402 ((USBHALHost*)p)->process();
sam_grove 5:3f93dd1d4cb3 403 }