ADC Niose test Connect four analog signals to your MBED. and then run the Windows app. The four traces are displayed on an oscilloscope like display. I have used a USB HID DEVICE link, so connections to D+, D- are required. The MBED code is otherwise quite basic, So you can modify it to your own test needs. Additionaly, there is a 16 bit count value, in my MBED code Mainly to test if MSB & LSB are correct.

Dependencies:   mbed

Committer:
ceri
Date:
Sat Nov 19 22:54:22 2011 +0000
Revision:
0:cbe01b678bd4
just enough to work

Who changed what in which revision?

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