Jason Engelman
/
USBCDC
Port of Keils USBCDC example, compiles ok. Gets stuck at init
usbhw.c@0:0b777ff85deb, 2010-07-05 (annotated)
- Committer:
- tecnosys
- Date:
- Mon Jul 05 10:16:57 2010 +0000
- Revision:
- 0:0b777ff85deb
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tecnosys | 0:0b777ff85deb | 1 | /*---------------------------------------------------------------------------- |
tecnosys | 0:0b777ff85deb | 2 | * U S B - K e r n e l |
tecnosys | 0:0b777ff85deb | 3 | *---------------------------------------------------------------------------- |
tecnosys | 0:0b777ff85deb | 4 | * Name: usbhw.c |
tecnosys | 0:0b777ff85deb | 5 | * Purpose: USB Hardware Layer Module for NXP's LPC17xx MCU |
tecnosys | 0:0b777ff85deb | 6 | * Version: V1.20 |
tecnosys | 0:0b777ff85deb | 7 | *---------------------------------------------------------------------------- |
tecnosys | 0:0b777ff85deb | 8 | * This software is supplied "AS IS" without any warranties, express, |
tecnosys | 0:0b777ff85deb | 9 | * implied or statutory, including but not limited to the implied |
tecnosys | 0:0b777ff85deb | 10 | * warranties of fitness for purpose, satisfactory quality and |
tecnosys | 0:0b777ff85deb | 11 | * noninfringement. Keil extends you a royalty-free right to reproduce |
tecnosys | 0:0b777ff85deb | 12 | * and distribute executable files created using this software for use |
tecnosys | 0:0b777ff85deb | 13 | * on NXP Semiconductors LPC family microcontroller devices only. Nothing |
tecnosys | 0:0b777ff85deb | 14 | * else gives you the right to use this software. |
tecnosys | 0:0b777ff85deb | 15 | * |
tecnosys | 0:0b777ff85deb | 16 | * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. |
tecnosys | 0:0b777ff85deb | 17 | *---------------------------------------------------------------------------- |
tecnosys | 0:0b777ff85deb | 18 | * History: |
tecnosys | 0:0b777ff85deb | 19 | * V1.20 Added USB_ClearEPBuf |
tecnosys | 0:0b777ff85deb | 20 | * V1.00 Initial Version |
tecnosys | 0:0b777ff85deb | 21 | *----------------------------------------------------------------------------*/ |
tecnosys | 0:0b777ff85deb | 22 | #include "LPC17xx.h" /* LPC17xx definitions */ |
tecnosys | 0:0b777ff85deb | 23 | //#include "LPC23xx.h" |
tecnosys | 0:0b777ff85deb | 24 | #include "usb.h" |
tecnosys | 0:0b777ff85deb | 25 | #include "usbcfg.h" |
tecnosys | 0:0b777ff85deb | 26 | #include "usbreg.h" |
tecnosys | 0:0b777ff85deb | 27 | #include "usbhw.h" |
tecnosys | 0:0b777ff85deb | 28 | #include "usbcore.h" |
tecnosys | 0:0b777ff85deb | 29 | #include "usbuser.h" |
tecnosys | 0:0b777ff85deb | 30 | |
tecnosys | 0:0b777ff85deb | 31 | |
tecnosys | 0:0b777ff85deb | 32 | #pragma diag_suppress 1441 |
tecnosys | 0:0b777ff85deb | 33 | |
tecnosys | 0:0b777ff85deb | 34 | |
tecnosys | 0:0b777ff85deb | 35 | #define EP_MSK_CTRL 0x0001 /* Control Endpoint Logical Address Mask */ |
tecnosys | 0:0b777ff85deb | 36 | #define EP_MSK_BULK 0xC924 /* Bulk Endpoint Logical Address Mask */ |
tecnosys | 0:0b777ff85deb | 37 | #define EP_MSK_INT 0x4492 /* Interrupt Endpoint Logical Address Mask */ |
tecnosys | 0:0b777ff85deb | 38 | #define EP_MSK_ISO 0x1248 /* Isochronous Endpoint Logical Address Mask */ |
tecnosys | 0:0b777ff85deb | 39 | |
tecnosys | 0:0b777ff85deb | 40 | |
tecnosys | 0:0b777ff85deb | 41 | #if USB_DMA |
tecnosys | 0:0b777ff85deb | 42 | |
tecnosys | 0:0b777ff85deb | 43 | #pragma arm section zidata = "USB_RAM" |
tecnosys | 0:0b777ff85deb | 44 | uint32_t UDCA[USB_EP_NUM]; /* UDCA in USB RAM */ |
tecnosys | 0:0b777ff85deb | 45 | uint32_t DD_NISO_Mem[4*DD_NISO_CNT]; /* Non-Iso DMA Descriptor Memory */ |
tecnosys | 0:0b777ff85deb | 46 | uint32_t DD_ISO_Mem [5*DD_ISO_CNT]; /* Iso DMA Descriptor Memory */ |
tecnosys | 0:0b777ff85deb | 47 | #pragma arm section zidata |
tecnosys | 0:0b777ff85deb | 48 | uint32_t udca[USB_EP_NUM]; /* UDCA saved values */ |
tecnosys | 0:0b777ff85deb | 49 | |
tecnosys | 0:0b777ff85deb | 50 | uint32_t DDMemMap[2]; /* DMA Descriptor Memory Usage */ |
tecnosys | 0:0b777ff85deb | 51 | |
tecnosys | 0:0b777ff85deb | 52 | #endif |
tecnosys | 0:0b777ff85deb | 53 | |
tecnosys | 0:0b777ff85deb | 54 | |
tecnosys | 0:0b777ff85deb | 55 | /* |
tecnosys | 0:0b777ff85deb | 56 | * Get Endpoint Physical Address |
tecnosys | 0:0b777ff85deb | 57 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 58 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 59 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 60 | * Return Value: Endpoint Physical Address |
tecnosys | 0:0b777ff85deb | 61 | */ |
tecnosys | 0:0b777ff85deb | 62 | |
tecnosys | 0:0b777ff85deb | 63 | uint32_t EPAdr (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 64 | uint32_t val; |
tecnosys | 0:0b777ff85deb | 65 | |
tecnosys | 0:0b777ff85deb | 66 | val = (EPNum & 0x0F) << 1; |
tecnosys | 0:0b777ff85deb | 67 | if (EPNum & 0x80) { |
tecnosys | 0:0b777ff85deb | 68 | val += 1; |
tecnosys | 0:0b777ff85deb | 69 | } |
tecnosys | 0:0b777ff85deb | 70 | return (val); |
tecnosys | 0:0b777ff85deb | 71 | } |
tecnosys | 0:0b777ff85deb | 72 | |
tecnosys | 0:0b777ff85deb | 73 | |
tecnosys | 0:0b777ff85deb | 74 | /* |
tecnosys | 0:0b777ff85deb | 75 | * Write Command |
tecnosys | 0:0b777ff85deb | 76 | * Parameters: cmd: Command |
tecnosys | 0:0b777ff85deb | 77 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 78 | */ |
tecnosys | 0:0b777ff85deb | 79 | |
tecnosys | 0:0b777ff85deb | 80 | void WrCmd (uint32_t cmd) { |
tecnosys | 0:0b777ff85deb | 81 | |
tecnosys | 0:0b777ff85deb | 82 | LPC_USB->USBDevIntClr = CCEMTY_INT; |
tecnosys | 0:0b777ff85deb | 83 | LPC_USB->USBCmdCode = cmd; |
tecnosys | 0:0b777ff85deb | 84 | while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); |
tecnosys | 0:0b777ff85deb | 85 | } |
tecnosys | 0:0b777ff85deb | 86 | |
tecnosys | 0:0b777ff85deb | 87 | |
tecnosys | 0:0b777ff85deb | 88 | /* |
tecnosys | 0:0b777ff85deb | 89 | * Write Command Data |
tecnosys | 0:0b777ff85deb | 90 | * Parameters: cmd: Command |
tecnosys | 0:0b777ff85deb | 91 | * val: Data |
tecnosys | 0:0b777ff85deb | 92 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 93 | */ |
tecnosys | 0:0b777ff85deb | 94 | |
tecnosys | 0:0b777ff85deb | 95 | void WrCmdDat (uint32_t cmd, uint32_t val) { |
tecnosys | 0:0b777ff85deb | 96 | |
tecnosys | 0:0b777ff85deb | 97 | LPC_USB->USBDevIntClr = CCEMTY_INT; |
tecnosys | 0:0b777ff85deb | 98 | LPC_USB->USBCmdCode = cmd; |
tecnosys | 0:0b777ff85deb | 99 | while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); |
tecnosys | 0:0b777ff85deb | 100 | LPC_USB->USBDevIntClr = CCEMTY_INT; |
tecnosys | 0:0b777ff85deb | 101 | LPC_USB->USBCmdCode = val; |
tecnosys | 0:0b777ff85deb | 102 | while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); |
tecnosys | 0:0b777ff85deb | 103 | } |
tecnosys | 0:0b777ff85deb | 104 | |
tecnosys | 0:0b777ff85deb | 105 | |
tecnosys | 0:0b777ff85deb | 106 | /* |
tecnosys | 0:0b777ff85deb | 107 | * Write Command to Endpoint |
tecnosys | 0:0b777ff85deb | 108 | * Parameters: cmd: Command |
tecnosys | 0:0b777ff85deb | 109 | * val: Data |
tecnosys | 0:0b777ff85deb | 110 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 111 | */ |
tecnosys | 0:0b777ff85deb | 112 | |
tecnosys | 0:0b777ff85deb | 113 | void WrCmdEP (uint32_t EPNum, uint32_t cmd){ |
tecnosys | 0:0b777ff85deb | 114 | |
tecnosys | 0:0b777ff85deb | 115 | LPC_USB->USBDevIntClr = CCEMTY_INT; |
tecnosys | 0:0b777ff85deb | 116 | LPC_USB->USBCmdCode = CMD_SEL_EP(EPAdr(EPNum)); |
tecnosys | 0:0b777ff85deb | 117 | while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); |
tecnosys | 0:0b777ff85deb | 118 | LPC_USB->USBDevIntClr = CCEMTY_INT; |
tecnosys | 0:0b777ff85deb | 119 | LPC_USB->USBCmdCode = cmd; |
tecnosys | 0:0b777ff85deb | 120 | while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); |
tecnosys | 0:0b777ff85deb | 121 | } |
tecnosys | 0:0b777ff85deb | 122 | |
tecnosys | 0:0b777ff85deb | 123 | |
tecnosys | 0:0b777ff85deb | 124 | /* |
tecnosys | 0:0b777ff85deb | 125 | * Read Command Data |
tecnosys | 0:0b777ff85deb | 126 | * Parameters: cmd: Command |
tecnosys | 0:0b777ff85deb | 127 | * Return Value: Data Value |
tecnosys | 0:0b777ff85deb | 128 | */ |
tecnosys | 0:0b777ff85deb | 129 | |
tecnosys | 0:0b777ff85deb | 130 | uint32_t RdCmdDat (uint32_t cmd) { |
tecnosys | 0:0b777ff85deb | 131 | |
tecnosys | 0:0b777ff85deb | 132 | LPC_USB->USBDevIntClr = CCEMTY_INT | CDFULL_INT; |
tecnosys | 0:0b777ff85deb | 133 | LPC_USB->USBCmdCode = cmd; |
tecnosys | 0:0b777ff85deb | 134 | while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0); |
tecnosys | 0:0b777ff85deb | 135 | return (LPC_USB->USBCmdData); |
tecnosys | 0:0b777ff85deb | 136 | } |
tecnosys | 0:0b777ff85deb | 137 | |
tecnosys | 0:0b777ff85deb | 138 | |
tecnosys | 0:0b777ff85deb | 139 | /* |
tecnosys | 0:0b777ff85deb | 140 | * USB Initialize Function |
tecnosys | 0:0b777ff85deb | 141 | * Called by the User to initialize USB |
tecnosys | 0:0b777ff85deb | 142 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 143 | */ |
tecnosys | 0:0b777ff85deb | 144 | |
tecnosys | 0:0b777ff85deb | 145 | void USB_Init (void) { |
tecnosys | 0:0b777ff85deb | 146 | |
tecnosys | 0:0b777ff85deb | 147 | LPC_PINCON->PINSEL1 &= ~((3<<26)|(3<<28)); /* P0.29 D+, P0.30 D- */ |
tecnosys | 0:0b777ff85deb | 148 | LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); /* PINSEL1 26.27, 28.29 = 01 */ |
tecnosys | 0:0b777ff85deb | 149 | |
tecnosys | 0:0b777ff85deb | 150 | LPC_PINCON->PINSEL3 &= ~((3<< 4)|(3<<28)); /* P1.18 GoodLink, P1.30 VBUS */ |
tecnosys | 0:0b777ff85deb | 151 | LPC_PINCON->PINSEL3 |= ((1<< 4)|(2<<28)); /* PINSEL3 4.5 = 01, 28.29 = 10 */ |
tecnosys | 0:0b777ff85deb | 152 | |
tecnosys | 0:0b777ff85deb | 153 | LPC_PINCON->PINSEL4 &= ~((3<<18) ); /* P2.9 SoftConnect */ |
tecnosys | 0:0b777ff85deb | 154 | LPC_PINCON->PINSEL4 |= ((1<<18) ); /* PINSEL4 18.19 = 01 */ |
tecnosys | 0:0b777ff85deb | 155 | |
tecnosys | 0:0b777ff85deb | 156 | LPC_SC->PCONP |= (1UL<<31); /* USB PCLK -> enable USB Per. */ |
tecnosys | 0:0b777ff85deb | 157 | |
tecnosys | 0:0b777ff85deb | 158 | LPC_USB->USBClkCtrl = 0x1A; /* Dev, PortSel, AHB clock enable */ |
tecnosys | 0:0b777ff85deb | 159 | while ((LPC_USB->USBClkSt & 0x1A) != 0x1A); |
tecnosys | 0:0b777ff85deb | 160 | |
tecnosys | 0:0b777ff85deb | 161 | NVIC_EnableIRQ(USB_IRQn); /* enable USB interrupt */ |
tecnosys | 0:0b777ff85deb | 162 | |
tecnosys | 0:0b777ff85deb | 163 | USB_Reset(); |
tecnosys | 0:0b777ff85deb | 164 | USB_SetAddress(0); |
tecnosys | 0:0b777ff85deb | 165 | } |
tecnosys | 0:0b777ff85deb | 166 | |
tecnosys | 0:0b777ff85deb | 167 | |
tecnosys | 0:0b777ff85deb | 168 | /* |
tecnosys | 0:0b777ff85deb | 169 | * USB Connect Function |
tecnosys | 0:0b777ff85deb | 170 | * Called by the User to Connect/Disconnect USB |
tecnosys | 0:0b777ff85deb | 171 | * Parameters: con: Connect/Disconnect |
tecnosys | 0:0b777ff85deb | 172 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 173 | */ |
tecnosys | 0:0b777ff85deb | 174 | |
tecnosys | 0:0b777ff85deb | 175 | void USB_Connect (uint32_t con) { |
tecnosys | 0:0b777ff85deb | 176 | WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0)); |
tecnosys | 0:0b777ff85deb | 177 | } |
tecnosys | 0:0b777ff85deb | 178 | |
tecnosys | 0:0b777ff85deb | 179 | |
tecnosys | 0:0b777ff85deb | 180 | /* |
tecnosys | 0:0b777ff85deb | 181 | * USB Reset Function |
tecnosys | 0:0b777ff85deb | 182 | * Called automatically on USB Reset |
tecnosys | 0:0b777ff85deb | 183 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 184 | */ |
tecnosys | 0:0b777ff85deb | 185 | |
tecnosys | 0:0b777ff85deb | 186 | void USB_Reset (void) { |
tecnosys | 0:0b777ff85deb | 187 | #if USB_DMA |
tecnosys | 0:0b777ff85deb | 188 | uint32_t n; |
tecnosys | 0:0b777ff85deb | 189 | #endif |
tecnosys | 0:0b777ff85deb | 190 | |
tecnosys | 0:0b777ff85deb | 191 | LPC_USB->USBEpInd = 0; |
tecnosys | 0:0b777ff85deb | 192 | LPC_USB->USBMaxPSize = USB_MAX_PACKET0; |
tecnosys | 0:0b777ff85deb | 193 | LPC_USB->USBEpInd = 1; |
tecnosys | 0:0b777ff85deb | 194 | LPC_USB->USBMaxPSize = USB_MAX_PACKET0; |
tecnosys | 0:0b777ff85deb | 195 | while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); |
tecnosys | 0:0b777ff85deb | 196 | |
tecnosys | 0:0b777ff85deb | 197 | LPC_USB->USBEpIntClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 198 | LPC_USB->USBEpIntEn = 0xFFFFFFFF ^ USB_DMA_EP; |
tecnosys | 0:0b777ff85deb | 199 | LPC_USB->USBDevIntClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 200 | LPC_USB->USBDevIntEn = DEV_STAT_INT | EP_SLOW_INT | |
tecnosys | 0:0b777ff85deb | 201 | (USB_SOF_EVENT ? FRAME_INT : 0) | |
tecnosys | 0:0b777ff85deb | 202 | (USB_ERROR_EVENT ? ERR_INT : 0); |
tecnosys | 0:0b777ff85deb | 203 | |
tecnosys | 0:0b777ff85deb | 204 | #if USB_DMA |
tecnosys | 0:0b777ff85deb | 205 | LPC_USB->USBUDCAH = USB_RAM_ADR; |
tecnosys | 0:0b777ff85deb | 206 | LPC_USB->USBDMARClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 207 | LPC_USB->USBEpDMADis = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 208 | LPC_USB->USBEpDMAEn = USB_DMA_EP; |
tecnosys | 0:0b777ff85deb | 209 | LPC_USB->USBEoTIntClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 210 | LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 211 | LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; |
tecnosys | 0:0b777ff85deb | 212 | LPC_USB->USBDMAIntEn = 0x00000007; |
tecnosys | 0:0b777ff85deb | 213 | DDMemMap[0] = 0x00000000; |
tecnosys | 0:0b777ff85deb | 214 | DDMemMap[1] = 0x00000000; |
tecnosys | 0:0b777ff85deb | 215 | for (n = 0; n < USB_EP_NUM; n++) { |
tecnosys | 0:0b777ff85deb | 216 | udca[n] = 0; |
tecnosys | 0:0b777ff85deb | 217 | UDCA[n] = 0; |
tecnosys | 0:0b777ff85deb | 218 | } |
tecnosys | 0:0b777ff85deb | 219 | #endif |
tecnosys | 0:0b777ff85deb | 220 | } |
tecnosys | 0:0b777ff85deb | 221 | |
tecnosys | 0:0b777ff85deb | 222 | |
tecnosys | 0:0b777ff85deb | 223 | /* |
tecnosys | 0:0b777ff85deb | 224 | * USB Suspend Function |
tecnosys | 0:0b777ff85deb | 225 | * Called automatically on USB Suspend |
tecnosys | 0:0b777ff85deb | 226 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 227 | */ |
tecnosys | 0:0b777ff85deb | 228 | |
tecnosys | 0:0b777ff85deb | 229 | void USB_Suspend (void) { |
tecnosys | 0:0b777ff85deb | 230 | /* Performed by Hardware */ |
tecnosys | 0:0b777ff85deb | 231 | } |
tecnosys | 0:0b777ff85deb | 232 | |
tecnosys | 0:0b777ff85deb | 233 | |
tecnosys | 0:0b777ff85deb | 234 | /* |
tecnosys | 0:0b777ff85deb | 235 | * USB Resume Function |
tecnosys | 0:0b777ff85deb | 236 | * Called automatically on USB Resume |
tecnosys | 0:0b777ff85deb | 237 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 238 | */ |
tecnosys | 0:0b777ff85deb | 239 | |
tecnosys | 0:0b777ff85deb | 240 | void USB_Resume (void) { |
tecnosys | 0:0b777ff85deb | 241 | /* Performed by Hardware */ |
tecnosys | 0:0b777ff85deb | 242 | } |
tecnosys | 0:0b777ff85deb | 243 | |
tecnosys | 0:0b777ff85deb | 244 | |
tecnosys | 0:0b777ff85deb | 245 | /* |
tecnosys | 0:0b777ff85deb | 246 | * USB Remote Wakeup Function |
tecnosys | 0:0b777ff85deb | 247 | * Called automatically on USB Remote Wakeup |
tecnosys | 0:0b777ff85deb | 248 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 249 | */ |
tecnosys | 0:0b777ff85deb | 250 | |
tecnosys | 0:0b777ff85deb | 251 | void USB_WakeUp (void) { |
tecnosys | 0:0b777ff85deb | 252 | |
tecnosys | 0:0b777ff85deb | 253 | if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) { |
tecnosys | 0:0b777ff85deb | 254 | WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); |
tecnosys | 0:0b777ff85deb | 255 | } |
tecnosys | 0:0b777ff85deb | 256 | } |
tecnosys | 0:0b777ff85deb | 257 | |
tecnosys | 0:0b777ff85deb | 258 | |
tecnosys | 0:0b777ff85deb | 259 | /* |
tecnosys | 0:0b777ff85deb | 260 | * USB Remote Wakeup Configuration Function |
tecnosys | 0:0b777ff85deb | 261 | * Parameters: cfg: Enable/Disable |
tecnosys | 0:0b777ff85deb | 262 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 263 | */ |
tecnosys | 0:0b777ff85deb | 264 | |
tecnosys | 0:0b777ff85deb | 265 | void USB_WakeUpCfg (uint32_t cfg) { |
tecnosys | 0:0b777ff85deb | 266 | /* Not needed */ |
tecnosys | 0:0b777ff85deb | 267 | } |
tecnosys | 0:0b777ff85deb | 268 | |
tecnosys | 0:0b777ff85deb | 269 | |
tecnosys | 0:0b777ff85deb | 270 | /* |
tecnosys | 0:0b777ff85deb | 271 | * USB Set Address Function |
tecnosys | 0:0b777ff85deb | 272 | * Parameters: adr: USB Address |
tecnosys | 0:0b777ff85deb | 273 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 274 | */ |
tecnosys | 0:0b777ff85deb | 275 | |
tecnosys | 0:0b777ff85deb | 276 | void USB_SetAddress (uint32_t adr) { |
tecnosys | 0:0b777ff85deb | 277 | WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */ |
tecnosys | 0:0b777ff85deb | 278 | WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */ |
tecnosys | 0:0b777ff85deb | 279 | } |
tecnosys | 0:0b777ff85deb | 280 | |
tecnosys | 0:0b777ff85deb | 281 | |
tecnosys | 0:0b777ff85deb | 282 | /* |
tecnosys | 0:0b777ff85deb | 283 | * USB Configure Function |
tecnosys | 0:0b777ff85deb | 284 | * Parameters: cfg: Configure/Deconfigure |
tecnosys | 0:0b777ff85deb | 285 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 286 | */ |
tecnosys | 0:0b777ff85deb | 287 | |
tecnosys | 0:0b777ff85deb | 288 | void USB_Configure (uint32_t cfg) { |
tecnosys | 0:0b777ff85deb | 289 | |
tecnosys | 0:0b777ff85deb | 290 | WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0)); |
tecnosys | 0:0b777ff85deb | 291 | |
tecnosys | 0:0b777ff85deb | 292 | LPC_USB->USBReEp = 0x00000003; |
tecnosys | 0:0b777ff85deb | 293 | while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); |
tecnosys | 0:0b777ff85deb | 294 | LPC_USB->USBDevIntClr = EP_RLZED_INT; |
tecnosys | 0:0b777ff85deb | 295 | } |
tecnosys | 0:0b777ff85deb | 296 | |
tecnosys | 0:0b777ff85deb | 297 | |
tecnosys | 0:0b777ff85deb | 298 | /* |
tecnosys | 0:0b777ff85deb | 299 | * Configure USB Endpoint according to Descriptor |
tecnosys | 0:0b777ff85deb | 300 | * Parameters: pEPD: Pointer to Endpoint Descriptor |
tecnosys | 0:0b777ff85deb | 301 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 302 | */ |
tecnosys | 0:0b777ff85deb | 303 | |
tecnosys | 0:0b777ff85deb | 304 | void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) { |
tecnosys | 0:0b777ff85deb | 305 | uint32_t num; |
tecnosys | 0:0b777ff85deb | 306 | |
tecnosys | 0:0b777ff85deb | 307 | num = EPAdr(pEPD->bEndpointAddress); |
tecnosys | 0:0b777ff85deb | 308 | LPC_USB->USBReEp |= (1 << num); |
tecnosys | 0:0b777ff85deb | 309 | LPC_USB->USBEpInd = num; |
tecnosys | 0:0b777ff85deb | 310 | LPC_USB->USBMaxPSize = pEPD->wMaxPacketSize; |
tecnosys | 0:0b777ff85deb | 311 | while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); |
tecnosys | 0:0b777ff85deb | 312 | LPC_USB->USBDevIntClr = EP_RLZED_INT; |
tecnosys | 0:0b777ff85deb | 313 | } |
tecnosys | 0:0b777ff85deb | 314 | |
tecnosys | 0:0b777ff85deb | 315 | |
tecnosys | 0:0b777ff85deb | 316 | /* |
tecnosys | 0:0b777ff85deb | 317 | * Set Direction for USB Control Endpoint |
tecnosys | 0:0b777ff85deb | 318 | * Parameters: dir: Out (dir == 0), In (dir <> 0) |
tecnosys | 0:0b777ff85deb | 319 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 320 | */ |
tecnosys | 0:0b777ff85deb | 321 | |
tecnosys | 0:0b777ff85deb | 322 | void USB_DirCtrlEP (uint32_t dir) { |
tecnosys | 0:0b777ff85deb | 323 | /* Not needed */ |
tecnosys | 0:0b777ff85deb | 324 | } |
tecnosys | 0:0b777ff85deb | 325 | |
tecnosys | 0:0b777ff85deb | 326 | |
tecnosys | 0:0b777ff85deb | 327 | /* |
tecnosys | 0:0b777ff85deb | 328 | * Enable USB Endpoint |
tecnosys | 0:0b777ff85deb | 329 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 330 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 331 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 332 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 333 | */ |
tecnosys | 0:0b777ff85deb | 334 | |
tecnosys | 0:0b777ff85deb | 335 | void USB_EnableEP (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 336 | WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); |
tecnosys | 0:0b777ff85deb | 337 | } |
tecnosys | 0:0b777ff85deb | 338 | |
tecnosys | 0:0b777ff85deb | 339 | |
tecnosys | 0:0b777ff85deb | 340 | /* |
tecnosys | 0:0b777ff85deb | 341 | * Disable USB Endpoint |
tecnosys | 0:0b777ff85deb | 342 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 343 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 344 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 345 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 346 | */ |
tecnosys | 0:0b777ff85deb | 347 | |
tecnosys | 0:0b777ff85deb | 348 | void USB_DisableEP (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 349 | WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA)); |
tecnosys | 0:0b777ff85deb | 350 | } |
tecnosys | 0:0b777ff85deb | 351 | |
tecnosys | 0:0b777ff85deb | 352 | |
tecnosys | 0:0b777ff85deb | 353 | /* |
tecnosys | 0:0b777ff85deb | 354 | * Reset USB Endpoint |
tecnosys | 0:0b777ff85deb | 355 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 356 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 357 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 358 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 359 | */ |
tecnosys | 0:0b777ff85deb | 360 | |
tecnosys | 0:0b777ff85deb | 361 | void USB_ResetEP (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 362 | WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); |
tecnosys | 0:0b777ff85deb | 363 | } |
tecnosys | 0:0b777ff85deb | 364 | |
tecnosys | 0:0b777ff85deb | 365 | |
tecnosys | 0:0b777ff85deb | 366 | /* |
tecnosys | 0:0b777ff85deb | 367 | * Set Stall for USB Endpoint |
tecnosys | 0:0b777ff85deb | 368 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 369 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 370 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 371 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 372 | */ |
tecnosys | 0:0b777ff85deb | 373 | |
tecnosys | 0:0b777ff85deb | 374 | void USB_SetStallEP (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 375 | WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST)); |
tecnosys | 0:0b777ff85deb | 376 | } |
tecnosys | 0:0b777ff85deb | 377 | |
tecnosys | 0:0b777ff85deb | 378 | |
tecnosys | 0:0b777ff85deb | 379 | /* |
tecnosys | 0:0b777ff85deb | 380 | * Clear Stall for USB Endpoint |
tecnosys | 0:0b777ff85deb | 381 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 382 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 383 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 384 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 385 | */ |
tecnosys | 0:0b777ff85deb | 386 | |
tecnosys | 0:0b777ff85deb | 387 | void USB_ClrStallEP (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 388 | WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); |
tecnosys | 0:0b777ff85deb | 389 | } |
tecnosys | 0:0b777ff85deb | 390 | |
tecnosys | 0:0b777ff85deb | 391 | |
tecnosys | 0:0b777ff85deb | 392 | /* |
tecnosys | 0:0b777ff85deb | 393 | * Clear USB Endpoint Buffer |
tecnosys | 0:0b777ff85deb | 394 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 395 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 396 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 397 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 398 | */ |
tecnosys | 0:0b777ff85deb | 399 | |
tecnosys | 0:0b777ff85deb | 400 | void USB_ClearEPBuf (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 401 | WrCmdEP(EPNum, CMD_CLR_BUF); |
tecnosys | 0:0b777ff85deb | 402 | } |
tecnosys | 0:0b777ff85deb | 403 | |
tecnosys | 0:0b777ff85deb | 404 | |
tecnosys | 0:0b777ff85deb | 405 | /* |
tecnosys | 0:0b777ff85deb | 406 | * Read USB Endpoint Data |
tecnosys | 0:0b777ff85deb | 407 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 408 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 409 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 410 | * pData: Pointer to Data Buffer |
tecnosys | 0:0b777ff85deb | 411 | * Return Value: Number of bytes read |
tecnosys | 0:0b777ff85deb | 412 | */ |
tecnosys | 0:0b777ff85deb | 413 | |
tecnosys | 0:0b777ff85deb | 414 | uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData) { |
tecnosys | 0:0b777ff85deb | 415 | uint32_t cnt, n; |
tecnosys | 0:0b777ff85deb | 416 | |
tecnosys | 0:0b777ff85deb | 417 | LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; |
tecnosys | 0:0b777ff85deb | 418 | |
tecnosys | 0:0b777ff85deb | 419 | do { |
tecnosys | 0:0b777ff85deb | 420 | cnt = LPC_USB->USBRxPLen; |
tecnosys | 0:0b777ff85deb | 421 | } while ((cnt & PKT_RDY) == 0); |
tecnosys | 0:0b777ff85deb | 422 | cnt &= PKT_LNGTH_MASK; |
tecnosys | 0:0b777ff85deb | 423 | |
tecnosys | 0:0b777ff85deb | 424 | for (n = 0; n < (cnt + 3) / 4; n++) { |
tecnosys | 0:0b777ff85deb | 425 | *((__packed uint32_t *)pData) = LPC_USB->USBRxData; |
tecnosys | 0:0b777ff85deb | 426 | pData += 4; |
tecnosys | 0:0b777ff85deb | 427 | } |
tecnosys | 0:0b777ff85deb | 428 | LPC_USB->USBCtrl = 0; |
tecnosys | 0:0b777ff85deb | 429 | |
tecnosys | 0:0b777ff85deb | 430 | if (((EP_MSK_ISO >> EPNum) & 1) == 0) { /* Non-Isochronous Endpoint */ |
tecnosys | 0:0b777ff85deb | 431 | WrCmdEP(EPNum, CMD_CLR_BUF); |
tecnosys | 0:0b777ff85deb | 432 | } |
tecnosys | 0:0b777ff85deb | 433 | |
tecnosys | 0:0b777ff85deb | 434 | return (cnt); |
tecnosys | 0:0b777ff85deb | 435 | } |
tecnosys | 0:0b777ff85deb | 436 | |
tecnosys | 0:0b777ff85deb | 437 | |
tecnosys | 0:0b777ff85deb | 438 | /* |
tecnosys | 0:0b777ff85deb | 439 | * Write USB Endpoint Data |
tecnosys | 0:0b777ff85deb | 440 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 441 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 442 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 443 | * pData: Pointer to Data Buffer |
tecnosys | 0:0b777ff85deb | 444 | * cnt: Number of bytes to write |
tecnosys | 0:0b777ff85deb | 445 | * Return Value: Number of bytes written |
tecnosys | 0:0b777ff85deb | 446 | */ |
tecnosys | 0:0b777ff85deb | 447 | |
tecnosys | 0:0b777ff85deb | 448 | uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) { |
tecnosys | 0:0b777ff85deb | 449 | uint32_t n; |
tecnosys | 0:0b777ff85deb | 450 | |
tecnosys | 0:0b777ff85deb | 451 | LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; |
tecnosys | 0:0b777ff85deb | 452 | |
tecnosys | 0:0b777ff85deb | 453 | LPC_USB->USBTxPLen = cnt; |
tecnosys | 0:0b777ff85deb | 454 | |
tecnosys | 0:0b777ff85deb | 455 | for (n = 0; n < (cnt + 3) / 4; n++) { |
tecnosys | 0:0b777ff85deb | 456 | LPC_USB->USBTxData = *((__packed uint32_t *)pData); |
tecnosys | 0:0b777ff85deb | 457 | pData += 4; |
tecnosys | 0:0b777ff85deb | 458 | } |
tecnosys | 0:0b777ff85deb | 459 | LPC_USB->USBCtrl = 0; |
tecnosys | 0:0b777ff85deb | 460 | WrCmdEP(EPNum, CMD_VALID_BUF); |
tecnosys | 0:0b777ff85deb | 461 | return (cnt); |
tecnosys | 0:0b777ff85deb | 462 | } |
tecnosys | 0:0b777ff85deb | 463 | |
tecnosys | 0:0b777ff85deb | 464 | #if USB_DMA |
tecnosys | 0:0b777ff85deb | 465 | |
tecnosys | 0:0b777ff85deb | 466 | /* DMA Descriptor Memory Layout */ |
tecnosys | 0:0b777ff85deb | 467 | const uint32_t DDAdr[2] = { DD_NISO_ADR, DD_ISO_ADR }; |
tecnosys | 0:0b777ff85deb | 468 | const uint32_t DDSz [2] = { 16, 20 }; |
tecnosys | 0:0b777ff85deb | 469 | |
tecnosys | 0:0b777ff85deb | 470 | |
tecnosys | 0:0b777ff85deb | 471 | /* |
tecnosys | 0:0b777ff85deb | 472 | * Setup USB DMA Transfer for selected Endpoint |
tecnosys | 0:0b777ff85deb | 473 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 474 | * pDD: Pointer to DMA Descriptor |
tecnosys | 0:0b777ff85deb | 475 | * Return Value: TRUE - Success, FALSE - Error |
tecnosys | 0:0b777ff85deb | 476 | */ |
tecnosys | 0:0b777ff85deb | 477 | |
tecnosys | 0:0b777ff85deb | 478 | uint32_t USB_DMA_Setup(uint32_t EPNum, USB_DMA_DESCRIPTOR *pDD) { |
tecnosys | 0:0b777ff85deb | 479 | uint32_t num, ptr, nxt, iso, n; |
tecnosys | 0:0b777ff85deb | 480 | |
tecnosys | 0:0b777ff85deb | 481 | iso = pDD->Cfg.Type.IsoEP; /* Iso or Non-Iso Descriptor */ |
tecnosys | 0:0b777ff85deb | 482 | num = EPAdr(EPNum); /* Endpoint's Physical Address */ |
tecnosys | 0:0b777ff85deb | 483 | |
tecnosys | 0:0b777ff85deb | 484 | ptr = 0; /* Current Descriptor */ |
tecnosys | 0:0b777ff85deb | 485 | nxt = udca[num]; /* Initial Descriptor */ |
tecnosys | 0:0b777ff85deb | 486 | while (nxt) { /* Go through Descriptor List */ |
tecnosys | 0:0b777ff85deb | 487 | ptr = nxt; /* Current Descriptor */ |
tecnosys | 0:0b777ff85deb | 488 | if (!pDD->Cfg.Type.Link) { /* Check for Linked Descriptors */ |
tecnosys | 0:0b777ff85deb | 489 | n = (ptr - DDAdr[iso]) / DDSz[iso]; /* Descriptor Index */ |
tecnosys | 0:0b777ff85deb | 490 | DDMemMap[iso] &= ~(1 << n); /* Unmark Memory Usage */ |
tecnosys | 0:0b777ff85deb | 491 | } |
tecnosys | 0:0b777ff85deb | 492 | nxt = *((uint32_t *)ptr); /* Next Descriptor */ |
tecnosys | 0:0b777ff85deb | 493 | } |
tecnosys | 0:0b777ff85deb | 494 | |
tecnosys | 0:0b777ff85deb | 495 | for (n = 0; n < 32; n++) { /* Search for available Memory */ |
tecnosys | 0:0b777ff85deb | 496 | if ((DDMemMap[iso] & (1 << n)) == 0) { |
tecnosys | 0:0b777ff85deb | 497 | break; /* Memory found */ |
tecnosys | 0:0b777ff85deb | 498 | } |
tecnosys | 0:0b777ff85deb | 499 | } |
tecnosys | 0:0b777ff85deb | 500 | if (n == 32) return (FALSE); /* Memory not available */ |
tecnosys | 0:0b777ff85deb | 501 | |
tecnosys | 0:0b777ff85deb | 502 | DDMemMap[iso] |= 1 << n; /* Mark Memory Usage */ |
tecnosys | 0:0b777ff85deb | 503 | nxt = DDAdr[iso] + n * DDSz[iso]; /* Next Descriptor */ |
tecnosys | 0:0b777ff85deb | 504 | |
tecnosys | 0:0b777ff85deb | 505 | if (ptr && pDD->Cfg.Type.Link) { |
tecnosys | 0:0b777ff85deb | 506 | *((uint32_t *)(ptr + 0)) = nxt; /* Link in new Descriptor */ |
tecnosys | 0:0b777ff85deb | 507 | *((uint32_t *)(ptr + 4)) |= 0x00000004; /* Next DD is Valid */ |
tecnosys | 0:0b777ff85deb | 508 | } else { |
tecnosys | 0:0b777ff85deb | 509 | udca[num] = nxt; /* Save new Descriptor */ |
tecnosys | 0:0b777ff85deb | 510 | UDCA[num] = nxt; /* Update UDCA in USB */ |
tecnosys | 0:0b777ff85deb | 511 | } |
tecnosys | 0:0b777ff85deb | 512 | |
tecnosys | 0:0b777ff85deb | 513 | /* Fill in DMA Descriptor */ |
tecnosys | 0:0b777ff85deb | 514 | *(((uint32_t *)nxt)++) = 0; /* Next DD Pointer */ |
tecnosys | 0:0b777ff85deb | 515 | *(((uint32_t *)nxt)++) = pDD->Cfg.Type.ATLE | |
tecnosys | 0:0b777ff85deb | 516 | (pDD->Cfg.Type.IsoEP << 4) | |
tecnosys | 0:0b777ff85deb | 517 | (pDD->MaxSize << 5) | |
tecnosys | 0:0b777ff85deb | 518 | (pDD->BufLen << 16); |
tecnosys | 0:0b777ff85deb | 519 | *(((uint32_t *)nxt)++) = pDD->BufAdr; |
tecnosys | 0:0b777ff85deb | 520 | *(((uint32_t *)nxt)++) = pDD->Cfg.Type.LenPos << 8; |
tecnosys | 0:0b777ff85deb | 521 | if (iso) { |
tecnosys | 0:0b777ff85deb | 522 | *((uint32_t *)nxt) = pDD->InfoAdr; |
tecnosys | 0:0b777ff85deb | 523 | } |
tecnosys | 0:0b777ff85deb | 524 | |
tecnosys | 0:0b777ff85deb | 525 | return (TRUE); /* Success */ |
tecnosys | 0:0b777ff85deb | 526 | } |
tecnosys | 0:0b777ff85deb | 527 | |
tecnosys | 0:0b777ff85deb | 528 | |
tecnosys | 0:0b777ff85deb | 529 | /* |
tecnosys | 0:0b777ff85deb | 530 | * Enable USB DMA Endpoint |
tecnosys | 0:0b777ff85deb | 531 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 532 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 533 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 534 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 535 | */ |
tecnosys | 0:0b777ff85deb | 536 | |
tecnosys | 0:0b777ff85deb | 537 | void USB_DMA_Enable (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 538 | LPC_USB->USBEpDMAEn = 1 << EPAdr(EPNum); |
tecnosys | 0:0b777ff85deb | 539 | } |
tecnosys | 0:0b777ff85deb | 540 | |
tecnosys | 0:0b777ff85deb | 541 | |
tecnosys | 0:0b777ff85deb | 542 | /* |
tecnosys | 0:0b777ff85deb | 543 | * Disable USB DMA Endpoint |
tecnosys | 0:0b777ff85deb | 544 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 545 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 546 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 547 | * Return Value: None |
tecnosys | 0:0b777ff85deb | 548 | */ |
tecnosys | 0:0b777ff85deb | 549 | |
tecnosys | 0:0b777ff85deb | 550 | void USB_DMA_Disable (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 551 | LPC_USB->USBEpDMADis = 1 << EPAdr(EPNum); |
tecnosys | 0:0b777ff85deb | 552 | } |
tecnosys | 0:0b777ff85deb | 553 | |
tecnosys | 0:0b777ff85deb | 554 | |
tecnosys | 0:0b777ff85deb | 555 | /* |
tecnosys | 0:0b777ff85deb | 556 | * Get USB DMA Endpoint Status |
tecnosys | 0:0b777ff85deb | 557 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 558 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 559 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 560 | * Return Value: DMA Status |
tecnosys | 0:0b777ff85deb | 561 | */ |
tecnosys | 0:0b777ff85deb | 562 | |
tecnosys | 0:0b777ff85deb | 563 | uint32_t USB_DMA_Status (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 564 | uint32_t ptr, val; |
tecnosys | 0:0b777ff85deb | 565 | |
tecnosys | 0:0b777ff85deb | 566 | ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ |
tecnosys | 0:0b777ff85deb | 567 | if (ptr == 0) |
tecnosys | 0:0b777ff85deb | 568 | return (USB_DMA_INVALID); |
tecnosys | 0:0b777ff85deb | 569 | |
tecnosys | 0:0b777ff85deb | 570 | val = *((uint32_t *)(ptr + 3*4)); /* Status Information */ |
tecnosys | 0:0b777ff85deb | 571 | switch ((val >> 1) & 0x0F) { |
tecnosys | 0:0b777ff85deb | 572 | case 0x00: /* Not serviced */ |
tecnosys | 0:0b777ff85deb | 573 | return (USB_DMA_IDLE); |
tecnosys | 0:0b777ff85deb | 574 | case 0x01: /* Being serviced */ |
tecnosys | 0:0b777ff85deb | 575 | return (USB_DMA_BUSY); |
tecnosys | 0:0b777ff85deb | 576 | case 0x02: /* Normal Completition */ |
tecnosys | 0:0b777ff85deb | 577 | return (USB_DMA_DONE); |
tecnosys | 0:0b777ff85deb | 578 | case 0x03: /* Data Under Run */ |
tecnosys | 0:0b777ff85deb | 579 | return (USB_DMA_UNDER_RUN); |
tecnosys | 0:0b777ff85deb | 580 | case 0x08: /* Data Over Run */ |
tecnosys | 0:0b777ff85deb | 581 | return (USB_DMA_OVER_RUN); |
tecnosys | 0:0b777ff85deb | 582 | case 0x09: /* System Error */ |
tecnosys | 0:0b777ff85deb | 583 | return (USB_DMA_ERROR); |
tecnosys | 0:0b777ff85deb | 584 | } |
tecnosys | 0:0b777ff85deb | 585 | |
tecnosys | 0:0b777ff85deb | 586 | return (USB_DMA_UNKNOWN); |
tecnosys | 0:0b777ff85deb | 587 | } |
tecnosys | 0:0b777ff85deb | 588 | |
tecnosys | 0:0b777ff85deb | 589 | |
tecnosys | 0:0b777ff85deb | 590 | /* |
tecnosys | 0:0b777ff85deb | 591 | * Get USB DMA Endpoint Current Buffer Address |
tecnosys | 0:0b777ff85deb | 592 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 593 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 594 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 595 | * Return Value: DMA Address (or -1 when DMA is Invalid) |
tecnosys | 0:0b777ff85deb | 596 | */ |
tecnosys | 0:0b777ff85deb | 597 | |
tecnosys | 0:0b777ff85deb | 598 | uint32_t USB_DMA_BufAdr (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 599 | uint32_t ptr, val; |
tecnosys | 0:0b777ff85deb | 600 | |
tecnosys | 0:0b777ff85deb | 601 | ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ |
tecnosys | 0:0b777ff85deb | 602 | if (ptr == 0) |
tecnosys | 0:0b777ff85deb | 603 | { |
tecnosys | 0:0b777ff85deb | 604 | return ((uint32_t)(-1)); /* DMA Invalid */ |
tecnosys | 0:0b777ff85deb | 605 | } |
tecnosys | 0:0b777ff85deb | 606 | |
tecnosys | 0:0b777ff85deb | 607 | val = *((uint32_t *)(ptr + 2*4)); /* Buffer Address */ |
tecnosys | 0:0b777ff85deb | 608 | return (val); /* Current Address */ |
tecnosys | 0:0b777ff85deb | 609 | } |
tecnosys | 0:0b777ff85deb | 610 | |
tecnosys | 0:0b777ff85deb | 611 | |
tecnosys | 0:0b777ff85deb | 612 | /* |
tecnosys | 0:0b777ff85deb | 613 | * Get USB DMA Endpoint Current Buffer Count |
tecnosys | 0:0b777ff85deb | 614 | * Number of transfered Bytes or Iso Packets |
tecnosys | 0:0b777ff85deb | 615 | * Parameters: EPNum: Endpoint Number |
tecnosys | 0:0b777ff85deb | 616 | * EPNum.0..3: Address |
tecnosys | 0:0b777ff85deb | 617 | * EPNum.7: Dir |
tecnosys | 0:0b777ff85deb | 618 | * Return Value: DMA Count (or -1 when DMA is Invalid) |
tecnosys | 0:0b777ff85deb | 619 | */ |
tecnosys | 0:0b777ff85deb | 620 | |
tecnosys | 0:0b777ff85deb | 621 | uint32_t USB_DMA_BufCnt (uint32_t EPNum) { |
tecnosys | 0:0b777ff85deb | 622 | uint32_t ptr, val; |
tecnosys | 0:0b777ff85deb | 623 | |
tecnosys | 0:0b777ff85deb | 624 | ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ |
tecnosys | 0:0b777ff85deb | 625 | if (ptr == 0) |
tecnosys | 0:0b777ff85deb | 626 | { |
tecnosys | 0:0b777ff85deb | 627 | return ((uint32_t)(-1)); /* DMA Invalid */ |
tecnosys | 0:0b777ff85deb | 628 | } |
tecnosys | 0:0b777ff85deb | 629 | val = *((uint32_t *)(ptr + 3*4)); /* Status Information */ |
tecnosys | 0:0b777ff85deb | 630 | return (val >> 16); /* Current Count */ |
tecnosys | 0:0b777ff85deb | 631 | } |
tecnosys | 0:0b777ff85deb | 632 | |
tecnosys | 0:0b777ff85deb | 633 | |
tecnosys | 0:0b777ff85deb | 634 | #endif /* USB_DMA */ |
tecnosys | 0:0b777ff85deb | 635 | |
tecnosys | 0:0b777ff85deb | 636 | |
tecnosys | 0:0b777ff85deb | 637 | /* |
tecnosys | 0:0b777ff85deb | 638 | * Get USB Last Frame Number |
tecnosys | 0:0b777ff85deb | 639 | * Parameters: None |
tecnosys | 0:0b777ff85deb | 640 | * Return Value: Frame Number |
tecnosys | 0:0b777ff85deb | 641 | */ |
tecnosys | 0:0b777ff85deb | 642 | |
tecnosys | 0:0b777ff85deb | 643 | uint32_t USB_GetFrame (void) { |
tecnosys | 0:0b777ff85deb | 644 | uint32_t val; |
tecnosys | 0:0b777ff85deb | 645 | |
tecnosys | 0:0b777ff85deb | 646 | WrCmd(CMD_RD_FRAME); |
tecnosys | 0:0b777ff85deb | 647 | val = RdCmdDat(DAT_RD_FRAME); |
tecnosys | 0:0b777ff85deb | 648 | val = val | (RdCmdDat(DAT_RD_FRAME) << 8); |
tecnosys | 0:0b777ff85deb | 649 | |
tecnosys | 0:0b777ff85deb | 650 | return (val); |
tecnosys | 0:0b777ff85deb | 651 | } |
tecnosys | 0:0b777ff85deb | 652 | |
tecnosys | 0:0b777ff85deb | 653 | |
tecnosys | 0:0b777ff85deb | 654 | /* |
tecnosys | 0:0b777ff85deb | 655 | * USB Interrupt Service Routine |
tecnosys | 0:0b777ff85deb | 656 | */ |
tecnosys | 0:0b777ff85deb | 657 | |
tecnosys | 0:0b777ff85deb | 658 | void USB_IRQHandler (void) { |
tecnosys | 0:0b777ff85deb | 659 | uint32_t disr, val, n, m; |
tecnosys | 0:0b777ff85deb | 660 | uint32_t episr, episrCur; |
tecnosys | 0:0b777ff85deb | 661 | |
tecnosys | 0:0b777ff85deb | 662 | disr = LPC_USB->USBDevIntSt; /* Device Interrupt Status */ |
tecnosys | 0:0b777ff85deb | 663 | |
tecnosys | 0:0b777ff85deb | 664 | /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ |
tecnosys | 0:0b777ff85deb | 665 | if (disr & DEV_STAT_INT) { |
tecnosys | 0:0b777ff85deb | 666 | LPC_USB->USBDevIntClr = DEV_STAT_INT; |
tecnosys | 0:0b777ff85deb | 667 | WrCmd(CMD_GET_DEV_STAT); |
tecnosys | 0:0b777ff85deb | 668 | val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */ |
tecnosys | 0:0b777ff85deb | 669 | if (val & DEV_RST) { /* Reset */ |
tecnosys | 0:0b777ff85deb | 670 | USB_Reset(); |
tecnosys | 0:0b777ff85deb | 671 | #if USB_RESET_EVENT |
tecnosys | 0:0b777ff85deb | 672 | USB_Reset_Event(); |
tecnosys | 0:0b777ff85deb | 673 | #endif |
tecnosys | 0:0b777ff85deb | 674 | } |
tecnosys | 0:0b777ff85deb | 675 | if (val & DEV_CON_CH) { /* Connect change */ |
tecnosys | 0:0b777ff85deb | 676 | #if USB_POWER_EVENT |
tecnosys | 0:0b777ff85deb | 677 | USB_Power_Event(val & DEV_CON); |
tecnosys | 0:0b777ff85deb | 678 | #endif |
tecnosys | 0:0b777ff85deb | 679 | } |
tecnosys | 0:0b777ff85deb | 680 | if (val & DEV_SUS_CH) { /* Suspend/Resume */ |
tecnosys | 0:0b777ff85deb | 681 | if (val & DEV_SUS) { /* Suspend */ |
tecnosys | 0:0b777ff85deb | 682 | USB_Suspend(); |
tecnosys | 0:0b777ff85deb | 683 | #if USB_SUSPEND_EVENT |
tecnosys | 0:0b777ff85deb | 684 | USB_Suspend_Event(); |
tecnosys | 0:0b777ff85deb | 685 | #endif |
tecnosys | 0:0b777ff85deb | 686 | } else { /* Resume */ |
tecnosys | 0:0b777ff85deb | 687 | USB_Resume(); |
tecnosys | 0:0b777ff85deb | 688 | #if USB_RESUME_EVENT |
tecnosys | 0:0b777ff85deb | 689 | USB_Resume_Event(); |
tecnosys | 0:0b777ff85deb | 690 | #endif |
tecnosys | 0:0b777ff85deb | 691 | } |
tecnosys | 0:0b777ff85deb | 692 | } |
tecnosys | 0:0b777ff85deb | 693 | goto isr_end; |
tecnosys | 0:0b777ff85deb | 694 | } |
tecnosys | 0:0b777ff85deb | 695 | |
tecnosys | 0:0b777ff85deb | 696 | #if USB_SOF_EVENT |
tecnosys | 0:0b777ff85deb | 697 | /* Start of Frame Interrupt */ |
tecnosys | 0:0b777ff85deb | 698 | if (disr & FRAME_INT) { |
tecnosys | 0:0b777ff85deb | 699 | USB_SOF_Event(); |
tecnosys | 0:0b777ff85deb | 700 | } |
tecnosys | 0:0b777ff85deb | 701 | #endif |
tecnosys | 0:0b777ff85deb | 702 | |
tecnosys | 0:0b777ff85deb | 703 | #if USB_ERROR_EVENT |
tecnosys | 0:0b777ff85deb | 704 | /* Error Interrupt */ |
tecnosys | 0:0b777ff85deb | 705 | if (disr & ERR_INT) { |
tecnosys | 0:0b777ff85deb | 706 | WrCmd(CMD_RD_ERR_STAT); |
tecnosys | 0:0b777ff85deb | 707 | val = RdCmdDat(DAT_RD_ERR_STAT); |
tecnosys | 0:0b777ff85deb | 708 | USB_Error_Event(val); |
tecnosys | 0:0b777ff85deb | 709 | } |
tecnosys | 0:0b777ff85deb | 710 | #endif |
tecnosys | 0:0b777ff85deb | 711 | |
tecnosys | 0:0b777ff85deb | 712 | /* Endpoint's Slow Interrupt */ |
tecnosys | 0:0b777ff85deb | 713 | if (disr & EP_SLOW_INT) { |
tecnosys | 0:0b777ff85deb | 714 | episrCur = 0; |
tecnosys | 0:0b777ff85deb | 715 | episr = LPC_USB->USBEpIntSt; |
tecnosys | 0:0b777ff85deb | 716 | for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */ |
tecnosys | 0:0b777ff85deb | 717 | if (episr == episrCur) break; /* break if all EP interrupts handled */ |
tecnosys | 0:0b777ff85deb | 718 | if (episr & (1 << n)) { |
tecnosys | 0:0b777ff85deb | 719 | episrCur |= (1 << n); |
tecnosys | 0:0b777ff85deb | 720 | m = n >> 1; |
tecnosys | 0:0b777ff85deb | 721 | |
tecnosys | 0:0b777ff85deb | 722 | LPC_USB->USBEpIntClr = (1 << n); |
tecnosys | 0:0b777ff85deb | 723 | while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0); |
tecnosys | 0:0b777ff85deb | 724 | val = LPC_USB->USBCmdData; |
tecnosys | 0:0b777ff85deb | 725 | |
tecnosys | 0:0b777ff85deb | 726 | if ((n & 1) == 0) { /* OUT Endpoint */ |
tecnosys | 0:0b777ff85deb | 727 | if (n == 0) { /* Control OUT Endpoint */ |
tecnosys | 0:0b777ff85deb | 728 | if (val & EP_SEL_STP) { /* Setup Packet */ |
tecnosys | 0:0b777ff85deb | 729 | if (USB_P_EP[0]) { |
tecnosys | 0:0b777ff85deb | 730 | USB_P_EP[0](USB_EVT_SETUP); |
tecnosys | 0:0b777ff85deb | 731 | continue; |
tecnosys | 0:0b777ff85deb | 732 | } |
tecnosys | 0:0b777ff85deb | 733 | } |
tecnosys | 0:0b777ff85deb | 734 | } |
tecnosys | 0:0b777ff85deb | 735 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 736 | USB_P_EP[m](USB_EVT_OUT); |
tecnosys | 0:0b777ff85deb | 737 | } |
tecnosys | 0:0b777ff85deb | 738 | } else { /* IN Endpoint */ |
tecnosys | 0:0b777ff85deb | 739 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 740 | USB_P_EP[m](USB_EVT_IN); |
tecnosys | 0:0b777ff85deb | 741 | } |
tecnosys | 0:0b777ff85deb | 742 | } |
tecnosys | 0:0b777ff85deb | 743 | } |
tecnosys | 0:0b777ff85deb | 744 | } |
tecnosys | 0:0b777ff85deb | 745 | LPC_USB->USBDevIntClr = EP_SLOW_INT; |
tecnosys | 0:0b777ff85deb | 746 | } |
tecnosys | 0:0b777ff85deb | 747 | |
tecnosys | 0:0b777ff85deb | 748 | #if USB_DMA |
tecnosys | 0:0b777ff85deb | 749 | |
tecnosys | 0:0b777ff85deb | 750 | if (LPC_USB->USBDMAIntSt & 0x00000001) { /* End of Transfer Interrupt */ |
tecnosys | 0:0b777ff85deb | 751 | val = LPC_USB->USBEoTIntSt; |
tecnosys | 0:0b777ff85deb | 752 | for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ |
tecnosys | 0:0b777ff85deb | 753 | if (val & (1 << n)) { |
tecnosys | 0:0b777ff85deb | 754 | m = n >> 1; |
tecnosys | 0:0b777ff85deb | 755 | if ((n & 1) == 0) { /* OUT Endpoint */ |
tecnosys | 0:0b777ff85deb | 756 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 757 | USB_P_EP[m](USB_EVT_OUT_DMA_EOT); |
tecnosys | 0:0b777ff85deb | 758 | } |
tecnosys | 0:0b777ff85deb | 759 | } else { /* IN Endpoint */ |
tecnosys | 0:0b777ff85deb | 760 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 761 | USB_P_EP[m](USB_EVT_IN_DMA_EOT); |
tecnosys | 0:0b777ff85deb | 762 | } |
tecnosys | 0:0b777ff85deb | 763 | } |
tecnosys | 0:0b777ff85deb | 764 | } |
tecnosys | 0:0b777ff85deb | 765 | } |
tecnosys | 0:0b777ff85deb | 766 | LPC_USB->USBEoTIntClr = val; |
tecnosys | 0:0b777ff85deb | 767 | } |
tecnosys | 0:0b777ff85deb | 768 | |
tecnosys | 0:0b777ff85deb | 769 | if (LPC_USB->USBDMAIntSt & 0x00000002) { /* New DD Request Interrupt */ |
tecnosys | 0:0b777ff85deb | 770 | val = LPC_USB->USBNDDRIntSt; |
tecnosys | 0:0b777ff85deb | 771 | for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ |
tecnosys | 0:0b777ff85deb | 772 | if (val & (1 << n)) { |
tecnosys | 0:0b777ff85deb | 773 | m = n >> 1; |
tecnosys | 0:0b777ff85deb | 774 | if ((n & 1) == 0) { /* OUT Endpoint */ |
tecnosys | 0:0b777ff85deb | 775 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 776 | USB_P_EP[m](USB_EVT_OUT_DMA_NDR); |
tecnosys | 0:0b777ff85deb | 777 | } |
tecnosys | 0:0b777ff85deb | 778 | } else { /* IN Endpoint */ |
tecnosys | 0:0b777ff85deb | 779 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 780 | USB_P_EP[m](USB_EVT_IN_DMA_NDR); |
tecnosys | 0:0b777ff85deb | 781 | } |
tecnosys | 0:0b777ff85deb | 782 | } |
tecnosys | 0:0b777ff85deb | 783 | } |
tecnosys | 0:0b777ff85deb | 784 | } |
tecnosys | 0:0b777ff85deb | 785 | LPC_USB->USBNDDRIntClr = val; |
tecnosys | 0:0b777ff85deb | 786 | } |
tecnosys | 0:0b777ff85deb | 787 | |
tecnosys | 0:0b777ff85deb | 788 | if (LPC_USB->USBDMAIntSt & 0x00000004) { /* System Error Interrupt */ |
tecnosys | 0:0b777ff85deb | 789 | val = LPC_USB->USBSysErrIntSt; |
tecnosys | 0:0b777ff85deb | 790 | for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ |
tecnosys | 0:0b777ff85deb | 791 | if (val & (1 << n)) { |
tecnosys | 0:0b777ff85deb | 792 | m = n >> 1; |
tecnosys | 0:0b777ff85deb | 793 | if ((n & 1) == 0) { /* OUT Endpoint */ |
tecnosys | 0:0b777ff85deb | 794 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 795 | USB_P_EP[m](USB_EVT_OUT_DMA_ERR); |
tecnosys | 0:0b777ff85deb | 796 | } |
tecnosys | 0:0b777ff85deb | 797 | } else { /* IN Endpoint */ |
tecnosys | 0:0b777ff85deb | 798 | if (USB_P_EP[m]) { |
tecnosys | 0:0b777ff85deb | 799 | USB_P_EP[m](USB_EVT_IN_DMA_ERR); |
tecnosys | 0:0b777ff85deb | 800 | } |
tecnosys | 0:0b777ff85deb | 801 | } |
tecnosys | 0:0b777ff85deb | 802 | } |
tecnosys | 0:0b777ff85deb | 803 | } |
tecnosys | 0:0b777ff85deb | 804 | LPC_USB->USBSysErrIntClr = val; |
tecnosys | 0:0b777ff85deb | 805 | } |
tecnosys | 0:0b777ff85deb | 806 | |
tecnosys | 0:0b777ff85deb | 807 | #endif /* USB_DMA */ |
tecnosys | 0:0b777ff85deb | 808 | |
tecnosys | 0:0b777ff85deb | 809 | isr_end: |
tecnosys | 0:0b777ff85deb | 810 | return; |
tecnosys | 0:0b777ff85deb | 811 | } |