This is early stages of my project, the idea of this project is to be able to mix a guitar with windows sounds in reverse such as instrumental background music or trance music perhaps or maybe another fellow guitarist you may have downloaded from the internet. Microphone or guitar pin is p19 I would use a microphone for drums:) and that it for the moment, the code makes the mbed act as usb speaker that excepts a guitar or microphone input, but with a twist it all in reverse like a guitar reverse effects pedal but only you can mix anything you can get from the internet or any windows sound.

Dependencies:   mbed

Committer:
mbed2f
Date:
Sun Jan 08 17:28:24 2012 +0000
Revision:
0:7610d342c76e

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed2f 0:7610d342c76e 1 // USBBusInterface_LPC17_LPC23.c
mbed2f 0:7610d342c76e 2 // USB Bus Interface for NXP LPC1768 and LPC2368
mbed2f 0:7610d342c76e 3 // Copyright (c) 2011 ARM Limited. All rights reserved.
mbed2f 0:7610d342c76e 4
mbed2f 0:7610d342c76e 5 #ifdef TARGET_LPC1768
mbed2f 0:7610d342c76e 6
mbed2f 0:7610d342c76e 7 #include "USBBusInterface.h"
mbed2f 0:7610d342c76e 8
mbed2f 0:7610d342c76e 9
mbed2f 0:7610d342c76e 10 // Get endpoint direction
mbed2f 0:7610d342c76e 11 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
mbed2f 0:7610d342c76e 12 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
mbed2f 0:7610d342c76e 13
mbed2f 0:7610d342c76e 14 // Convert physical endpoint number to register bit
mbed2f 0:7610d342c76e 15 #define EP(endpoint) (1UL<<endpoint)
mbed2f 0:7610d342c76e 16
mbed2f 0:7610d342c76e 17 // Power Control for Peripherals register
mbed2f 0:7610d342c76e 18 #define PCUSB (1UL<<31)
mbed2f 0:7610d342c76e 19
mbed2f 0:7610d342c76e 20 // USB Clock Control register
mbed2f 0:7610d342c76e 21 #define DEV_CLK_EN (1UL<<1)
mbed2f 0:7610d342c76e 22 #define AHB_CLK_EN (1UL<<4)
mbed2f 0:7610d342c76e 23
mbed2f 0:7610d342c76e 24 // USB Clock Status register
mbed2f 0:7610d342c76e 25 #define DEV_CLK_ON (1UL<<1)
mbed2f 0:7610d342c76e 26 #define AHB_CLK_ON (1UL<<4)
mbed2f 0:7610d342c76e 27
mbed2f 0:7610d342c76e 28 // USB Device Interupt registers
mbed2f 0:7610d342c76e 29 #define FRAME (1UL<<0)
mbed2f 0:7610d342c76e 30 #define EP_FAST (1UL<<1)
mbed2f 0:7610d342c76e 31 #define EP_SLOW (1UL<<2)
mbed2f 0:7610d342c76e 32 #define DEV_STAT (1UL<<3)
mbed2f 0:7610d342c76e 33 #define CCEMPTY (1UL<<4)
mbed2f 0:7610d342c76e 34 #define CDFULL (1UL<<5)
mbed2f 0:7610d342c76e 35 #define RxENDPKT (1UL<<6)
mbed2f 0:7610d342c76e 36 #define TxENDPKT (1UL<<7)
mbed2f 0:7610d342c76e 37 #define EP_RLZED (1UL<<8)
mbed2f 0:7610d342c76e 38 #define ERR_INT (1UL<<9)
mbed2f 0:7610d342c76e 39
mbed2f 0:7610d342c76e 40 // USB Control register
mbed2f 0:7610d342c76e 41 #define RD_EN (1<<0)
mbed2f 0:7610d342c76e 42 #define WR_EN (1<<1)
mbed2f 0:7610d342c76e 43 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
mbed2f 0:7610d342c76e 44
mbed2f 0:7610d342c76e 45 // USB Receive Packet Length register
mbed2f 0:7610d342c76e 46 #define DV (1UL<<10)
mbed2f 0:7610d342c76e 47 #define PKT_RDY (1UL<<11)
mbed2f 0:7610d342c76e 48 #define PKT_LNGTH_MASK (0x3ff)
mbed2f 0:7610d342c76e 49
mbed2f 0:7610d342c76e 50 // Serial Interface Engine (SIE)
mbed2f 0:7610d342c76e 51 #define SIE_WRITE (0x01)
mbed2f 0:7610d342c76e 52 #define SIE_READ (0x02)
mbed2f 0:7610d342c76e 53 #define SIE_COMMAND (0x05)
mbed2f 0:7610d342c76e 54 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
mbed2f 0:7610d342c76e 55
mbed2f 0:7610d342c76e 56 // SIE Command codes
mbed2f 0:7610d342c76e 57 #define SIE_CMD_SET_ADDRESS (0xD0)
mbed2f 0:7610d342c76e 58 #define SIE_CMD_CONFIGURE_DEVICE (0xD8)
mbed2f 0:7610d342c76e 59 #define SIE_CMD_SET_MODE (0xF3)
mbed2f 0:7610d342c76e 60 #define SIE_CMD_READ_FRAME_NUMBER (0xF5)
mbed2f 0:7610d342c76e 61 #define SIE_CMD_READ_TEST_REGISTER (0xFD)
mbed2f 0:7610d342c76e 62 #define SIE_CMD_SET_DEVICE_STATUS (0xFE)
mbed2f 0:7610d342c76e 63 #define SIE_CMD_GET_DEVICE_STATUS (0xFE)
mbed2f 0:7610d342c76e 64 #define SIE_CMD_GET_ERROR_CODE (0xFF)
mbed2f 0:7610d342c76e 65 #define SIE_CMD_READ_ERROR_STATUS (0xFB)
mbed2f 0:7610d342c76e 66
mbed2f 0:7610d342c76e 67 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint)
mbed2f 0:7610d342c76e 68 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
mbed2f 0:7610d342c76e 69 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint)
mbed2f 0:7610d342c76e 70
mbed2f 0:7610d342c76e 71 #define SIE_CMD_CLEAR_BUFFER (0xF2)
mbed2f 0:7610d342c76e 72 #define SIE_CMD_VALIDATE_BUFFER (0xFA)
mbed2f 0:7610d342c76e 73
mbed2f 0:7610d342c76e 74 // SIE Device Status register
mbed2f 0:7610d342c76e 75 #define SIE_DS_CON (1<<0)
mbed2f 0:7610d342c76e 76 #define SIE_DS_CON_CH (1<<1)
mbed2f 0:7610d342c76e 77 #define SIE_DS_SUS (1<<2)
mbed2f 0:7610d342c76e 78 #define SIE_DS_SUS_CH (1<<3)
mbed2f 0:7610d342c76e 79 #define SIE_DS_RST (1<<4)
mbed2f 0:7610d342c76e 80
mbed2f 0:7610d342c76e 81 // SIE Device Set Address register
mbed2f 0:7610d342c76e 82 #define SIE_DSA_DEV_EN (1<<7)
mbed2f 0:7610d342c76e 83
mbed2f 0:7610d342c76e 84 // SIE Configue Device register
mbed2f 0:7610d342c76e 85 #define SIE_CONF_DEVICE (1<<0)
mbed2f 0:7610d342c76e 86
mbed2f 0:7610d342c76e 87 // Select Endpoint register
mbed2f 0:7610d342c76e 88 #define SIE_SE_FE (1<<0)
mbed2f 0:7610d342c76e 89 #define SIE_SE_ST (1<<1)
mbed2f 0:7610d342c76e 90 #define SIE_SE_STP (1<<2)
mbed2f 0:7610d342c76e 91 #define SIE_SE_PO (1<<3)
mbed2f 0:7610d342c76e 92 #define SIE_SE_EPN (1<<4)
mbed2f 0:7610d342c76e 93 #define SIE_SE_B_1_FULL (1<<5)
mbed2f 0:7610d342c76e 94 #define SIE_SE_B_2_FULL (1<<6)
mbed2f 0:7610d342c76e 95
mbed2f 0:7610d342c76e 96 // Set Endpoint Status command
mbed2f 0:7610d342c76e 97 #define SIE_SES_ST (1<<0)
mbed2f 0:7610d342c76e 98 #define SIE_SES_DA (1<<5)
mbed2f 0:7610d342c76e 99 #define SIE_SES_RF_MO (1<<6)
mbed2f 0:7610d342c76e 100 #define SIE_SES_CND_ST (1<<7)
mbed2f 0:7610d342c76e 101
mbed2f 0:7610d342c76e 102
mbed2f 0:7610d342c76e 103 USBHAL * USBHAL::instance;
mbed2f 0:7610d342c76e 104
mbed2f 0:7610d342c76e 105 volatile int epComplete;
mbed2f 0:7610d342c76e 106 uint32_t endpointStallState;
mbed2f 0:7610d342c76e 107
mbed2f 0:7610d342c76e 108 static void SIECommand(uint32_t command) {
mbed2f 0:7610d342c76e 109 // The command phase of a SIE transaction
mbed2f 0:7610d342c76e 110 LPC_USB->USBDevIntClr = CCEMPTY;
mbed2f 0:7610d342c76e 111 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
mbed2f 0:7610d342c76e 112 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
mbed2f 0:7610d342c76e 113 }
mbed2f 0:7610d342c76e 114
mbed2f 0:7610d342c76e 115 static void SIEWriteData(uint8_t data) {
mbed2f 0:7610d342c76e 116 // The data write phase of a SIE transaction
mbed2f 0:7610d342c76e 117 LPC_USB->USBDevIntClr = CCEMPTY;
mbed2f 0:7610d342c76e 118 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
mbed2f 0:7610d342c76e 119 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
mbed2f 0:7610d342c76e 120 }
mbed2f 0:7610d342c76e 121
mbed2f 0:7610d342c76e 122 static uint8_t SIEReadData(uint32_t command) {
mbed2f 0:7610d342c76e 123 // The data read phase of a SIE transaction
mbed2f 0:7610d342c76e 124 LPC_USB->USBDevIntClr = CDFULL;
mbed2f 0:7610d342c76e 125 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
mbed2f 0:7610d342c76e 126 while (!(LPC_USB->USBDevIntSt & CDFULL));
mbed2f 0:7610d342c76e 127 return (uint8_t)LPC_USB->USBCmdData;
mbed2f 0:7610d342c76e 128 }
mbed2f 0:7610d342c76e 129
mbed2f 0:7610d342c76e 130 static void SIEsetDeviceStatus(uint8_t status) {
mbed2f 0:7610d342c76e 131 // Write SIE device status register
mbed2f 0:7610d342c76e 132 SIECommand(SIE_CMD_SET_DEVICE_STATUS);
mbed2f 0:7610d342c76e 133 SIEWriteData(status);
mbed2f 0:7610d342c76e 134 }
mbed2f 0:7610d342c76e 135
mbed2f 0:7610d342c76e 136 static uint8_t SIEgetDeviceStatus(void) {
mbed2f 0:7610d342c76e 137 // Read SIE device status register
mbed2f 0:7610d342c76e 138 SIECommand(SIE_CMD_GET_DEVICE_STATUS);
mbed2f 0:7610d342c76e 139 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
mbed2f 0:7610d342c76e 140 }
mbed2f 0:7610d342c76e 141
mbed2f 0:7610d342c76e 142 void SIEsetAddress(uint8_t address) {
mbed2f 0:7610d342c76e 143 // Write SIE device address register
mbed2f 0:7610d342c76e 144 SIECommand(SIE_CMD_SET_ADDRESS);
mbed2f 0:7610d342c76e 145 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
mbed2f 0:7610d342c76e 146 }
mbed2f 0:7610d342c76e 147
mbed2f 0:7610d342c76e 148 static uint8_t SIEselectEndpoint(uint8_t endpoint) {
mbed2f 0:7610d342c76e 149 // SIE select endpoint command
mbed2f 0:7610d342c76e 150 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
mbed2f 0:7610d342c76e 151 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
mbed2f 0:7610d342c76e 152 }
mbed2f 0:7610d342c76e 153
mbed2f 0:7610d342c76e 154 static uint8_t SIEclearBuffer(void) {
mbed2f 0:7610d342c76e 155 // SIE clear buffer command
mbed2f 0:7610d342c76e 156 SIECommand(SIE_CMD_CLEAR_BUFFER);
mbed2f 0:7610d342c76e 157 return SIEReadData(SIE_CMD_CLEAR_BUFFER);
mbed2f 0:7610d342c76e 158 }
mbed2f 0:7610d342c76e 159
mbed2f 0:7610d342c76e 160 static void SIEvalidateBuffer(void) {
mbed2f 0:7610d342c76e 161 // SIE validate buffer command
mbed2f 0:7610d342c76e 162 SIECommand(SIE_CMD_VALIDATE_BUFFER);
mbed2f 0:7610d342c76e 163 }
mbed2f 0:7610d342c76e 164
mbed2f 0:7610d342c76e 165 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) {
mbed2f 0:7610d342c76e 166 // SIE set endpoint status command
mbed2f 0:7610d342c76e 167 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
mbed2f 0:7610d342c76e 168 SIEWriteData(status);
mbed2f 0:7610d342c76e 169 }
mbed2f 0:7610d342c76e 170
mbed2f 0:7610d342c76e 171 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
mbed2f 0:7610d342c76e 172 static uint16_t SIEgetFrameNumber(void) {
mbed2f 0:7610d342c76e 173 // Read current frame number
mbed2f 0:7610d342c76e 174 uint16_t lowByte;
mbed2f 0:7610d342c76e 175 uint16_t highByte;
mbed2f 0:7610d342c76e 176
mbed2f 0:7610d342c76e 177 SIECommand(SIE_CMD_READ_FRAME_NUMBER);
mbed2f 0:7610d342c76e 178 lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
mbed2f 0:7610d342c76e 179 highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
mbed2f 0:7610d342c76e 180
mbed2f 0:7610d342c76e 181 return (highByte << 8) | lowByte;
mbed2f 0:7610d342c76e 182 }
mbed2f 0:7610d342c76e 183
mbed2f 0:7610d342c76e 184 static void SIEconfigureDevice(void) {
mbed2f 0:7610d342c76e 185 // SIE Configure device command
mbed2f 0:7610d342c76e 186 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
mbed2f 0:7610d342c76e 187 SIEWriteData(SIE_CONF_DEVICE);
mbed2f 0:7610d342c76e 188 }
mbed2f 0:7610d342c76e 189
mbed2f 0:7610d342c76e 190 static void SIEunconfigureDevice(void) {
mbed2f 0:7610d342c76e 191 // SIE Configure device command
mbed2f 0:7610d342c76e 192 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
mbed2f 0:7610d342c76e 193 SIEWriteData(0);
mbed2f 0:7610d342c76e 194 }
mbed2f 0:7610d342c76e 195
mbed2f 0:7610d342c76e 196 static void SIEconnect(void) {
mbed2f 0:7610d342c76e 197 // Connect USB device
mbed2f 0:7610d342c76e 198 uint8_t status;
mbed2f 0:7610d342c76e 199
mbed2f 0:7610d342c76e 200 status = SIEgetDeviceStatus();
mbed2f 0:7610d342c76e 201 SIEsetDeviceStatus(status | SIE_DS_CON);
mbed2f 0:7610d342c76e 202 }
mbed2f 0:7610d342c76e 203
mbed2f 0:7610d342c76e 204
mbed2f 0:7610d342c76e 205 static void SIEdisconnect(void) {
mbed2f 0:7610d342c76e 206 // Disconnect USB device
mbed2f 0:7610d342c76e 207 uint8_t status;
mbed2f 0:7610d342c76e 208
mbed2f 0:7610d342c76e 209 status = SIEgetDeviceStatus();
mbed2f 0:7610d342c76e 210 SIEsetDeviceStatus(status & ~SIE_DS_CON);
mbed2f 0:7610d342c76e 211 }
mbed2f 0:7610d342c76e 212
mbed2f 0:7610d342c76e 213
mbed2f 0:7610d342c76e 214 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) {
mbed2f 0:7610d342c76e 215 // Implemented using using EP_INT_CLR.
mbed2f 0:7610d342c76e 216 LPC_USB->USBEpIntClr = EP(endpoint);
mbed2f 0:7610d342c76e 217 while (!(LPC_USB->USBDevIntSt & CDFULL));
mbed2f 0:7610d342c76e 218 return (uint8_t)LPC_USB->USBCmdData;
mbed2f 0:7610d342c76e 219 }
mbed2f 0:7610d342c76e 220
mbed2f 0:7610d342c76e 221
mbed2f 0:7610d342c76e 222
mbed2f 0:7610d342c76e 223
mbed2f 0:7610d342c76e 224
mbed2f 0:7610d342c76e 225 static void enableEndpointEvent(uint8_t endpoint) {
mbed2f 0:7610d342c76e 226 // Enable an endpoint interrupt
mbed2f 0:7610d342c76e 227 LPC_USB->USBEpIntEn |= EP(endpoint);
mbed2f 0:7610d342c76e 228 }
mbed2f 0:7610d342c76e 229
mbed2f 0:7610d342c76e 230 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
mbed2f 0:7610d342c76e 231 static void disableEndpointEvent(uint8_t endpoint) {
mbed2f 0:7610d342c76e 232 // Disable an endpoint interrupt
mbed2f 0:7610d342c76e 233 LPC_USB->USBEpIntEn &= ~EP(endpoint);
mbed2f 0:7610d342c76e 234 }
mbed2f 0:7610d342c76e 235
mbed2f 0:7610d342c76e 236 static volatile uint32_t __attribute__((used)) dummyRead;
mbed2f 0:7610d342c76e 237
mbed2f 0:7610d342c76e 238
mbed2f 0:7610d342c76e 239 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
mbed2f 0:7610d342c76e 240 // Read from an OUT endpoint
mbed2f 0:7610d342c76e 241 uint32_t size;
mbed2f 0:7610d342c76e 242 uint32_t i;
mbed2f 0:7610d342c76e 243 uint32_t data = 0;
mbed2f 0:7610d342c76e 244 uint8_t offset;
mbed2f 0:7610d342c76e 245
mbed2f 0:7610d342c76e 246 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
mbed2f 0:7610d342c76e 247 while (!(LPC_USB->USBRxPLen & PKT_RDY));
mbed2f 0:7610d342c76e 248
mbed2f 0:7610d342c76e 249 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
mbed2f 0:7610d342c76e 250
mbed2f 0:7610d342c76e 251 offset = 0;
mbed2f 0:7610d342c76e 252
mbed2f 0:7610d342c76e 253 if (size > 0) {
mbed2f 0:7610d342c76e 254 for (i=0; i<size; i++) {
mbed2f 0:7610d342c76e 255 if (offset==0) {
mbed2f 0:7610d342c76e 256 // Fetch up to four bytes of data as a word
mbed2f 0:7610d342c76e 257 data = LPC_USB->USBRxData;
mbed2f 0:7610d342c76e 258 }
mbed2f 0:7610d342c76e 259
mbed2f 0:7610d342c76e 260 // extract a byte
mbed2f 0:7610d342c76e 261 *buffer = (data>>offset) & 0xff;
mbed2f 0:7610d342c76e 262 buffer++;
mbed2f 0:7610d342c76e 263
mbed2f 0:7610d342c76e 264 // move on to the next byte
mbed2f 0:7610d342c76e 265 offset = (offset + 8) % 32;
mbed2f 0:7610d342c76e 266 }
mbed2f 0:7610d342c76e 267 } else {
mbed2f 0:7610d342c76e 268 dummyRead = LPC_USB->USBRxData;
mbed2f 0:7610d342c76e 269 }
mbed2f 0:7610d342c76e 270
mbed2f 0:7610d342c76e 271 LPC_USB->USBCtrl = 0;
mbed2f 0:7610d342c76e 272
mbed2f 0:7610d342c76e 273 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
mbed2f 0:7610d342c76e 274 SIEselectEndpoint(endpoint);
mbed2f 0:7610d342c76e 275 SIEclearBuffer();
mbed2f 0:7610d342c76e 276 }
mbed2f 0:7610d342c76e 277
mbed2f 0:7610d342c76e 278 return size;
mbed2f 0:7610d342c76e 279 }
mbed2f 0:7610d342c76e 280
mbed2f 0:7610d342c76e 281 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) {
mbed2f 0:7610d342c76e 282 // Write to an IN endpoint
mbed2f 0:7610d342c76e 283 uint32_t temp, data;
mbed2f 0:7610d342c76e 284 uint8_t offset;
mbed2f 0:7610d342c76e 285
mbed2f 0:7610d342c76e 286 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
mbed2f 0:7610d342c76e 287
mbed2f 0:7610d342c76e 288 LPC_USB->USBTxPLen = size;
mbed2f 0:7610d342c76e 289 offset = 0;
mbed2f 0:7610d342c76e 290 data = 0;
mbed2f 0:7610d342c76e 291
mbed2f 0:7610d342c76e 292 if (size>0) {
mbed2f 0:7610d342c76e 293 do {
mbed2f 0:7610d342c76e 294 // Fetch next data byte into a word-sized temporary variable
mbed2f 0:7610d342c76e 295 temp = *buffer++;
mbed2f 0:7610d342c76e 296
mbed2f 0:7610d342c76e 297 // Add to current data word
mbed2f 0:7610d342c76e 298 temp = temp << offset;
mbed2f 0:7610d342c76e 299 data = data | temp;
mbed2f 0:7610d342c76e 300
mbed2f 0:7610d342c76e 301 // move on to the next byte
mbed2f 0:7610d342c76e 302 offset = (offset + 8) % 32;
mbed2f 0:7610d342c76e 303 size--;
mbed2f 0:7610d342c76e 304
mbed2f 0:7610d342c76e 305 if ((offset==0) || (size==0)) {
mbed2f 0:7610d342c76e 306 // Write the word to the endpoint
mbed2f 0:7610d342c76e 307 LPC_USB->USBTxData = data;
mbed2f 0:7610d342c76e 308 data = 0;
mbed2f 0:7610d342c76e 309 }
mbed2f 0:7610d342c76e 310 } while (size>0);
mbed2f 0:7610d342c76e 311 } else {
mbed2f 0:7610d342c76e 312 LPC_USB->USBTxData = 0;
mbed2f 0:7610d342c76e 313 }
mbed2f 0:7610d342c76e 314
mbed2f 0:7610d342c76e 315 // Clear WR_EN to cover zero length packet case
mbed2f 0:7610d342c76e 316 LPC_USB->USBCtrl=0;
mbed2f 0:7610d342c76e 317
mbed2f 0:7610d342c76e 318 SIEselectEndpoint(endpoint);
mbed2f 0:7610d342c76e 319 SIEvalidateBuffer();
mbed2f 0:7610d342c76e 320 }
mbed2f 0:7610d342c76e 321
mbed2f 0:7610d342c76e 322
mbed2f 0:7610d342c76e 323
mbed2f 0:7610d342c76e 324
mbed2f 0:7610d342c76e 325
mbed2f 0:7610d342c76e 326
mbed2f 0:7610d342c76e 327
mbed2f 0:7610d342c76e 328 USBHAL::USBHAL(void) {
mbed2f 0:7610d342c76e 329 // Disable IRQ
mbed2f 0:7610d342c76e 330 NVIC_DisableIRQ(USB_IRQn);
mbed2f 0:7610d342c76e 331
mbed2f 0:7610d342c76e 332 // Enable power to USB device controller
mbed2f 0:7610d342c76e 333 LPC_SC->PCONP |= PCUSB;
mbed2f 0:7610d342c76e 334
mbed2f 0:7610d342c76e 335 // Enable USB clocks
mbed2f 0:7610d342c76e 336 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
mbed2f 0:7610d342c76e 337 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
mbed2f 0:7610d342c76e 338
mbed2f 0:7610d342c76e 339 // Configure pins P0.29 and P0.30 to be USB D+ and USB D-
mbed2f 0:7610d342c76e 340 LPC_PINCON->PINSEL1 &= 0xc3ffffff;
mbed2f 0:7610d342c76e 341 LPC_PINCON->PINSEL1 |= 0x14000000;
mbed2f 0:7610d342c76e 342
mbed2f 0:7610d342c76e 343 // Disconnect USB device
mbed2f 0:7610d342c76e 344 SIEdisconnect();
mbed2f 0:7610d342c76e 345
mbed2f 0:7610d342c76e 346 // Configure pin P2.9 to be Connect
mbed2f 0:7610d342c76e 347 LPC_PINCON->PINSEL4 &= 0xfffcffff;
mbed2f 0:7610d342c76e 348 LPC_PINCON->PINSEL4 |= 0x00040000;
mbed2f 0:7610d342c76e 349
mbed2f 0:7610d342c76e 350 // Connect must be low for at least 2.5uS
mbed2f 0:7610d342c76e 351 wait(0.3);
mbed2f 0:7610d342c76e 352
mbed2f 0:7610d342c76e 353 // Set the maximum packet size for the control endpoints
mbed2f 0:7610d342c76e 354 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
mbed2f 0:7610d342c76e 355 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
mbed2f 0:7610d342c76e 356
mbed2f 0:7610d342c76e 357 // Attach IRQ
mbed2f 0:7610d342c76e 358 instance = this;
mbed2f 0:7610d342c76e 359 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
mbed2f 0:7610d342c76e 360 NVIC_EnableIRQ(USB_IRQn);
mbed2f 0:7610d342c76e 361
mbed2f 0:7610d342c76e 362 // Enable interrupts for device events and EP0
mbed2f 0:7610d342c76e 363 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
mbed2f 0:7610d342c76e 364 enableEndpointEvent(EP0IN);
mbed2f 0:7610d342c76e 365 enableEndpointEvent(EP0OUT);
mbed2f 0:7610d342c76e 366 }
mbed2f 0:7610d342c76e 367
mbed2f 0:7610d342c76e 368 USBHAL::~USBHAL(void) {
mbed2f 0:7610d342c76e 369 // Ensure device disconnected
mbed2f 0:7610d342c76e 370 SIEdisconnect();
mbed2f 0:7610d342c76e 371
mbed2f 0:7610d342c76e 372 // Disable USB interrupts
mbed2f 0:7610d342c76e 373 NVIC_DisableIRQ(USB_IRQn);
mbed2f 0:7610d342c76e 374 }
mbed2f 0:7610d342c76e 375
mbed2f 0:7610d342c76e 376 void USBHAL::connect(void) {
mbed2f 0:7610d342c76e 377 // Connect USB device
mbed2f 0:7610d342c76e 378 SIEconnect();
mbed2f 0:7610d342c76e 379 }
mbed2f 0:7610d342c76e 380
mbed2f 0:7610d342c76e 381 void USBHAL::disconnect(void) {
mbed2f 0:7610d342c76e 382 // Disconnect USB device
mbed2f 0:7610d342c76e 383 SIEdisconnect();
mbed2f 0:7610d342c76e 384 }
mbed2f 0:7610d342c76e 385
mbed2f 0:7610d342c76e 386 void USBHAL::configureDevice(void) {
mbed2f 0:7610d342c76e 387 SIEconfigureDevice();
mbed2f 0:7610d342c76e 388 }
mbed2f 0:7610d342c76e 389
mbed2f 0:7610d342c76e 390 void USBHAL::unconfigureDevice(void) {
mbed2f 0:7610d342c76e 391 SIEunconfigureDevice();
mbed2f 0:7610d342c76e 392 }
mbed2f 0:7610d342c76e 393
mbed2f 0:7610d342c76e 394 void USBHAL::setAddress(uint8_t address) {
mbed2f 0:7610d342c76e 395 SIEsetAddress(address);
mbed2f 0:7610d342c76e 396 }
mbed2f 0:7610d342c76e 397
mbed2f 0:7610d342c76e 398 void USBHAL::EP0setup(uint8_t *buffer) {
mbed2f 0:7610d342c76e 399 endpointReadcore(EP0OUT, buffer);
mbed2f 0:7610d342c76e 400 }
mbed2f 0:7610d342c76e 401
mbed2f 0:7610d342c76e 402 void USBHAL::EP0read(void) {
mbed2f 0:7610d342c76e 403 // Not required
mbed2f 0:7610d342c76e 404 }
mbed2f 0:7610d342c76e 405
mbed2f 0:7610d342c76e 406 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
mbed2f 0:7610d342c76e 407 return endpointReadcore(EP0OUT, buffer);
mbed2f 0:7610d342c76e 408 }
mbed2f 0:7610d342c76e 409
mbed2f 0:7610d342c76e 410 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
mbed2f 0:7610d342c76e 411 endpointWritecore(EP0IN, buffer, size);
mbed2f 0:7610d342c76e 412 }
mbed2f 0:7610d342c76e 413
mbed2f 0:7610d342c76e 414 void USBHAL::EP0getWriteResult(void) {
mbed2f 0:7610d342c76e 415 // Not required
mbed2f 0:7610d342c76e 416 }
mbed2f 0:7610d342c76e 417
mbed2f 0:7610d342c76e 418 void USBHAL::EP0stall(void) {
mbed2f 0:7610d342c76e 419 // This will stall both control endpoints
mbed2f 0:7610d342c76e 420 stallEndpoint(EP0OUT);
mbed2f 0:7610d342c76e 421 }
mbed2f 0:7610d342c76e 422
mbed2f 0:7610d342c76e 423 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
mbed2f 0:7610d342c76e 424 return EP_PENDING;
mbed2f 0:7610d342c76e 425 }
mbed2f 0:7610d342c76e 426
mbed2f 0:7610d342c76e 427 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
mbed2f 0:7610d342c76e 428
mbed2f 0:7610d342c76e 429 //for isochronous endpoint, we don't wait an interrupt
mbed2f 0:7610d342c76e 430 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
mbed2f 0:7610d342c76e 431 if (!(epComplete & EP(endpoint)))
mbed2f 0:7610d342c76e 432 return EP_PENDING;
mbed2f 0:7610d342c76e 433 }
mbed2f 0:7610d342c76e 434
mbed2f 0:7610d342c76e 435 *bytesRead = endpointReadcore(endpoint, buffer);
mbed2f 0:7610d342c76e 436 epComplete &= ~EP(endpoint);
mbed2f 0:7610d342c76e 437 return EP_COMPLETED;
mbed2f 0:7610d342c76e 438 }
mbed2f 0:7610d342c76e 439
mbed2f 0:7610d342c76e 440 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
mbed2f 0:7610d342c76e 441 if (getEndpointStallState(endpoint)) {
mbed2f 0:7610d342c76e 442 return EP_STALLED;
mbed2f 0:7610d342c76e 443 }
mbed2f 0:7610d342c76e 444
mbed2f 0:7610d342c76e 445 epComplete &= ~EP(endpoint);
mbed2f 0:7610d342c76e 446
mbed2f 0:7610d342c76e 447 endpointWritecore(endpoint, data, size);
mbed2f 0:7610d342c76e 448 return EP_PENDING;
mbed2f 0:7610d342c76e 449 }
mbed2f 0:7610d342c76e 450
mbed2f 0:7610d342c76e 451 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
mbed2f 0:7610d342c76e 452 if (epComplete & EP(endpoint)) {
mbed2f 0:7610d342c76e 453 epComplete &= ~EP(endpoint);
mbed2f 0:7610d342c76e 454 return EP_COMPLETED;
mbed2f 0:7610d342c76e 455 }
mbed2f 0:7610d342c76e 456
mbed2f 0:7610d342c76e 457 return EP_PENDING;
mbed2f 0:7610d342c76e 458 }
mbed2f 0:7610d342c76e 459
mbed2f 0:7610d342c76e 460 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
mbed2f 0:7610d342c76e 461 // Realise an endpoint
mbed2f 0:7610d342c76e 462 LPC_USB->USBDevIntClr = EP_RLZED;
mbed2f 0:7610d342c76e 463 LPC_USB->USBReEp |= EP(endpoint);
mbed2f 0:7610d342c76e 464 LPC_USB->USBEpInd = endpoint;
mbed2f 0:7610d342c76e 465 LPC_USB->USBMaxPSize = maxPacket;
mbed2f 0:7610d342c76e 466
mbed2f 0:7610d342c76e 467 while (!(LPC_USB->USBDevIntSt & EP_RLZED));
mbed2f 0:7610d342c76e 468 LPC_USB->USBDevIntClr = EP_RLZED;
mbed2f 0:7610d342c76e 469
mbed2f 0:7610d342c76e 470 // Clear stall state
mbed2f 0:7610d342c76e 471 endpointStallState &= ~EP(endpoint);
mbed2f 0:7610d342c76e 472
mbed2f 0:7610d342c76e 473 enableEndpointEvent(endpoint);
mbed2f 0:7610d342c76e 474 return true;
mbed2f 0:7610d342c76e 475 }
mbed2f 0:7610d342c76e 476
mbed2f 0:7610d342c76e 477 void USBHAL::stallEndpoint(uint8_t endpoint) {
mbed2f 0:7610d342c76e 478 // Stall an endpoint
mbed2f 0:7610d342c76e 479 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) {
mbed2f 0:7610d342c76e 480 // Conditionally stall both control endpoints
mbed2f 0:7610d342c76e 481 SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
mbed2f 0:7610d342c76e 482 } else {
mbed2f 0:7610d342c76e 483 SIEsetEndpointStatus(endpoint, SIE_SES_ST);
mbed2f 0:7610d342c76e 484
mbed2f 0:7610d342c76e 485 // Update stall state
mbed2f 0:7610d342c76e 486 endpointStallState |= EP(endpoint);
mbed2f 0:7610d342c76e 487 }
mbed2f 0:7610d342c76e 488 }
mbed2f 0:7610d342c76e 489
mbed2f 0:7610d342c76e 490 void USBHAL::unstallEndpoint(uint8_t endpoint) {
mbed2f 0:7610d342c76e 491 // Unstall an endpoint. The endpoint will also be reinitialised
mbed2f 0:7610d342c76e 492 SIEsetEndpointStatus(endpoint, 0);
mbed2f 0:7610d342c76e 493
mbed2f 0:7610d342c76e 494 // Update stall state
mbed2f 0:7610d342c76e 495 endpointStallState &= ~EP(endpoint);
mbed2f 0:7610d342c76e 496 }
mbed2f 0:7610d342c76e 497
mbed2f 0:7610d342c76e 498 bool USBHAL::getEndpointStallState(uint8_t endpoint) {
mbed2f 0:7610d342c76e 499 // Returns true if endpoint stalled
mbed2f 0:7610d342c76e 500 return endpointStallState & EP(endpoint);
mbed2f 0:7610d342c76e 501 }
mbed2f 0:7610d342c76e 502
mbed2f 0:7610d342c76e 503 void USBHAL::remoteWakeup(void) {
mbed2f 0:7610d342c76e 504 // Remote wakeup
mbed2f 0:7610d342c76e 505 uint8_t status;
mbed2f 0:7610d342c76e 506
mbed2f 0:7610d342c76e 507 // Enable USB clocks
mbed2f 0:7610d342c76e 508 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
mbed2f 0:7610d342c76e 509 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
mbed2f 0:7610d342c76e 510
mbed2f 0:7610d342c76e 511 status = SIEgetDeviceStatus();
mbed2f 0:7610d342c76e 512 SIEsetDeviceStatus(status & ~SIE_DS_SUS);
mbed2f 0:7610d342c76e 513 }
mbed2f 0:7610d342c76e 514
mbed2f 0:7610d342c76e 515
mbed2f 0:7610d342c76e 516
mbed2f 0:7610d342c76e 517
mbed2f 0:7610d342c76e 518
mbed2f 0:7610d342c76e 519 void USBHAL::_usbisr(void) {
mbed2f 0:7610d342c76e 520 instance->usbisr();
mbed2f 0:7610d342c76e 521 }
mbed2f 0:7610d342c76e 522
mbed2f 0:7610d342c76e 523
mbed2f 0:7610d342c76e 524 void USBHAL::usbisr(void) {
mbed2f 0:7610d342c76e 525 uint8_t devStat;
mbed2f 0:7610d342c76e 526
mbed2f 0:7610d342c76e 527 if (LPC_USB->USBDevIntSt & FRAME) {
mbed2f 0:7610d342c76e 528 // Start of frame event
mbed2f 0:7610d342c76e 529 SOF(SIEgetFrameNumber());
mbed2f 0:7610d342c76e 530 // Clear interrupt status flag
mbed2f 0:7610d342c76e 531 LPC_USB->USBDevIntClr = FRAME;
mbed2f 0:7610d342c76e 532 }
mbed2f 0:7610d342c76e 533
mbed2f 0:7610d342c76e 534 if (LPC_USB->USBDevIntSt & DEV_STAT) {
mbed2f 0:7610d342c76e 535 // Device Status interrupt
mbed2f 0:7610d342c76e 536 // Must clear the interrupt status flag before reading the device status from the SIE
mbed2f 0:7610d342c76e 537 LPC_USB->USBDevIntClr = DEV_STAT;
mbed2f 0:7610d342c76e 538
mbed2f 0:7610d342c76e 539 // Read device status from SIE
mbed2f 0:7610d342c76e 540 devStat = SIEgetDeviceStatus();
mbed2f 0:7610d342c76e 541
mbed2f 0:7610d342c76e 542 if (devStat & SIE_DS_RST) {
mbed2f 0:7610d342c76e 543 // Bus reset
mbed2f 0:7610d342c76e 544 busReset();
mbed2f 0:7610d342c76e 545 }
mbed2f 0:7610d342c76e 546 }
mbed2f 0:7610d342c76e 547
mbed2f 0:7610d342c76e 548 if (LPC_USB->USBDevIntSt & EP_SLOW) {
mbed2f 0:7610d342c76e 549 // (Slow) Endpoint Interrupt
mbed2f 0:7610d342c76e 550
mbed2f 0:7610d342c76e 551 // Process each endpoint interrupt
mbed2f 0:7610d342c76e 552 if (LPC_USB->USBEpIntSt & EP(EP0OUT)) {
mbed2f 0:7610d342c76e 553 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
mbed2f 0:7610d342c76e 554 // this is a setup packet
mbed2f 0:7610d342c76e 555 EP0setupCallback();
mbed2f 0:7610d342c76e 556 } else {
mbed2f 0:7610d342c76e 557 EP0out();
mbed2f 0:7610d342c76e 558 }
mbed2f 0:7610d342c76e 559 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 560 }
mbed2f 0:7610d342c76e 561
mbed2f 0:7610d342c76e 562 if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
mbed2f 0:7610d342c76e 563 selectEndpointClearInterrupt(EP0IN);
mbed2f 0:7610d342c76e 564 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 565 EP0in();
mbed2f 0:7610d342c76e 566 }
mbed2f 0:7610d342c76e 567
mbed2f 0:7610d342c76e 568 // TODO: This should cover all endpoints, not just EP1,2,3:
mbed2f 0:7610d342c76e 569 if (LPC_USB->USBEpIntSt & EP(EP1IN)) {
mbed2f 0:7610d342c76e 570 selectEndpointClearInterrupt(EP1IN);
mbed2f 0:7610d342c76e 571 epComplete |= EP(EP1IN);
mbed2f 0:7610d342c76e 572 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 573 if (EP1_IN_callback())
mbed2f 0:7610d342c76e 574 epComplete &= ~EP(EP1IN);
mbed2f 0:7610d342c76e 575 }
mbed2f 0:7610d342c76e 576
mbed2f 0:7610d342c76e 577 if (LPC_USB->USBEpIntSt & EP(EP1OUT)) {
mbed2f 0:7610d342c76e 578 selectEndpointClearInterrupt(EP1OUT);
mbed2f 0:7610d342c76e 579 epComplete |= EP(EP1OUT);
mbed2f 0:7610d342c76e 580 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 581 if (EP1_OUT_callback())
mbed2f 0:7610d342c76e 582 epComplete &= ~EP(EP1OUT);
mbed2f 0:7610d342c76e 583 }
mbed2f 0:7610d342c76e 584
mbed2f 0:7610d342c76e 585 if (LPC_USB->USBEpIntSt & EP(EP2IN)) {
mbed2f 0:7610d342c76e 586 selectEndpointClearInterrupt(EP2IN);
mbed2f 0:7610d342c76e 587 epComplete |= EP(EP2IN);
mbed2f 0:7610d342c76e 588 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 589 if (EP2_IN_callback())
mbed2f 0:7610d342c76e 590 epComplete &= ~EP(EP2IN);
mbed2f 0:7610d342c76e 591 }
mbed2f 0:7610d342c76e 592
mbed2f 0:7610d342c76e 593 if (LPC_USB->USBEpIntSt & EP(EP2OUT)) {
mbed2f 0:7610d342c76e 594 selectEndpointClearInterrupt(EP2OUT);
mbed2f 0:7610d342c76e 595 epComplete |= EP(EP2OUT);
mbed2f 0:7610d342c76e 596 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 597 if (EP2_OUT_callback())
mbed2f 0:7610d342c76e 598 epComplete &= ~EP(EP2OUT);
mbed2f 0:7610d342c76e 599 }
mbed2f 0:7610d342c76e 600
mbed2f 0:7610d342c76e 601 if (LPC_USB->USBEpIntSt & EP(EP3IN)) {
mbed2f 0:7610d342c76e 602 selectEndpointClearInterrupt(EP3IN);
mbed2f 0:7610d342c76e 603 epComplete |= EP(EP3IN);
mbed2f 0:7610d342c76e 604 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 605 if (EP3_IN_callback())
mbed2f 0:7610d342c76e 606 epComplete &= ~EP(EP3IN);
mbed2f 0:7610d342c76e 607 }
mbed2f 0:7610d342c76e 608
mbed2f 0:7610d342c76e 609 if (LPC_USB->USBEpIntSt & EP(EP3OUT)) {
mbed2f 0:7610d342c76e 610 selectEndpointClearInterrupt(EP3OUT);
mbed2f 0:7610d342c76e 611 epComplete |= EP(EP3OUT);
mbed2f 0:7610d342c76e 612 LPC_USB->USBDevIntClr = EP_SLOW;
mbed2f 0:7610d342c76e 613 if (EP3_OUT_callback())
mbed2f 0:7610d342c76e 614 epComplete &= ~EP(EP3OUT);
mbed2f 0:7610d342c76e 615 }
mbed2f 0:7610d342c76e 616 }
mbed2f 0:7610d342c76e 617 }
mbed2f 0:7610d342c76e 618
mbed2f 0:7610d342c76e 619 #endif