These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!

Committer:
frank26080115
Date:
Sun Mar 20 05:38:56 2011 +0000
Revision:
0:bf7b9fba3924

        

Who changed what in which revision?

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