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.
USBBusInterface_LPC17_LPC23.cpp
00001 // USBBusInterface_LPC17_LPC23.c 00002 // USB Bus Interface for NXP LPC1768 and LPC2368 00003 // Copyright (c) 2011 ARM Limited. All rights reserved. 00004 00005 #ifdef TARGET_LPC1768 00006 00007 #include "USBBusInterface.h" 00008 00009 00010 // Get endpoint direction 00011 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false) 00012 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) 00013 00014 // Convert physical endpoint number to register bit 00015 #define EP(endpoint) (1UL<<endpoint) 00016 00017 // Power Control for Peripherals register 00018 #define PCUSB (1UL<<31) 00019 00020 // USB Clock Control register 00021 #define DEV_CLK_EN (1UL<<1) 00022 #define AHB_CLK_EN (1UL<<4) 00023 00024 // USB Clock Status register 00025 #define DEV_CLK_ON (1UL<<1) 00026 #define AHB_CLK_ON (1UL<<4) 00027 00028 // USB Device Interupt registers 00029 #define FRAME (1UL<<0) 00030 #define EP_FAST (1UL<<1) 00031 #define EP_SLOW (1UL<<2) 00032 #define DEV_STAT (1UL<<3) 00033 #define CCEMPTY (1UL<<4) 00034 #define CDFULL (1UL<<5) 00035 #define RxENDPKT (1UL<<6) 00036 #define TxENDPKT (1UL<<7) 00037 #define EP_RLZED (1UL<<8) 00038 #define ERR_INT (1UL<<9) 00039 00040 // USB Control register 00041 #define RD_EN (1<<0) 00042 #define WR_EN (1<<1) 00043 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) 00044 00045 // USB Receive Packet Length register 00046 #define DV (1UL<<10) 00047 #define PKT_RDY (1UL<<11) 00048 #define PKT_LNGTH_MASK (0x3ff) 00049 00050 // Serial Interface Engine (SIE) 00051 #define SIE_WRITE (0x01) 00052 #define SIE_READ (0x02) 00053 #define SIE_COMMAND (0x05) 00054 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) 00055 00056 // SIE Command codes 00057 #define SIE_CMD_SET_ADDRESS (0xD0) 00058 #define SIE_CMD_CONFIGURE_DEVICE (0xD8) 00059 #define SIE_CMD_SET_MODE (0xF3) 00060 #define SIE_CMD_READ_FRAME_NUMBER (0xF5) 00061 #define SIE_CMD_READ_TEST_REGISTER (0xFD) 00062 #define SIE_CMD_SET_DEVICE_STATUS (0xFE) 00063 #define SIE_CMD_GET_DEVICE_STATUS (0xFE) 00064 #define SIE_CMD_GET_ERROR_CODE (0xFF) 00065 #define SIE_CMD_READ_ERROR_STATUS (0xFB) 00066 00067 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) 00068 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) 00069 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) 00070 00071 #define SIE_CMD_CLEAR_BUFFER (0xF2) 00072 #define SIE_CMD_VALIDATE_BUFFER (0xFA) 00073 00074 // SIE Device Status register 00075 #define SIE_DS_CON (1<<0) 00076 #define SIE_DS_CON_CH (1<<1) 00077 #define SIE_DS_SUS (1<<2) 00078 #define SIE_DS_SUS_CH (1<<3) 00079 #define SIE_DS_RST (1<<4) 00080 00081 // SIE Device Set Address register 00082 #define SIE_DSA_DEV_EN (1<<7) 00083 00084 // SIE Configue Device register 00085 #define SIE_CONF_DEVICE (1<<0) 00086 00087 // Select Endpoint register 00088 #define SIE_SE_FE (1<<0) 00089 #define SIE_SE_ST (1<<1) 00090 #define SIE_SE_STP (1<<2) 00091 #define SIE_SE_PO (1<<3) 00092 #define SIE_SE_EPN (1<<4) 00093 #define SIE_SE_B_1_FULL (1<<5) 00094 #define SIE_SE_B_2_FULL (1<<6) 00095 00096 // Set Endpoint Status command 00097 #define SIE_SES_ST (1<<0) 00098 #define SIE_SES_DA (1<<5) 00099 #define SIE_SES_RF_MO (1<<6) 00100 #define SIE_SES_CND_ST (1<<7) 00101 00102 00103 USBHAL * USBHAL::instance; 00104 00105 volatile int epComplete; 00106 uint32_t endpointStallState; 00107 00108 static void SIECommand(uint32_t command) 00109 { 00110 // The command phase of a SIE transaction 00111 LPC_USB->USBDevIntClr = CCEMPTY; 00112 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command); 00113 while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 00114 } 00115 00116 static void SIEWriteData(uint8_t data) 00117 { 00118 // The data write phase of a SIE transaction 00119 LPC_USB->USBDevIntClr = CCEMPTY; 00120 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data); 00121 while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 00122 } 00123 00124 static uint8_t SIEReadData(uint32_t command) 00125 { 00126 // The data read phase of a SIE transaction 00127 LPC_USB->USBDevIntClr = CDFULL; 00128 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command); 00129 while (!(LPC_USB->USBDevIntSt & CDFULL)); 00130 return (uint8_t)LPC_USB->USBCmdData; 00131 } 00132 00133 static void SIEsetDeviceStatus(uint8_t status) 00134 { 00135 // Write SIE device status register 00136 SIECommand(SIE_CMD_SET_DEVICE_STATUS); 00137 SIEWriteData(status); 00138 } 00139 00140 static uint8_t SIEgetDeviceStatus(void) 00141 { 00142 // Read SIE device status register 00143 SIECommand(SIE_CMD_GET_DEVICE_STATUS); 00144 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS); 00145 } 00146 00147 void SIEsetAddress(uint8_t address) 00148 { 00149 // Write SIE device address register 00150 SIECommand(SIE_CMD_SET_ADDRESS); 00151 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN); 00152 } 00153 00154 static uint8_t SIEselectEndpoint(uint8_t endpoint) 00155 { 00156 // SIE select endpoint command 00157 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00158 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00159 } 00160 00161 static uint8_t SIEclearBuffer(void) 00162 { 00163 // SIE clear buffer command 00164 SIECommand(SIE_CMD_CLEAR_BUFFER); 00165 return SIEReadData(SIE_CMD_CLEAR_BUFFER); 00166 } 00167 00168 static void SIEvalidateBuffer(void) 00169 { 00170 // SIE validate buffer command 00171 SIECommand(SIE_CMD_VALIDATE_BUFFER); 00172 } 00173 00174 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) 00175 { 00176 // SIE set endpoint status command 00177 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint)); 00178 SIEWriteData(status); 00179 } 00180 00181 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused)); 00182 static uint16_t SIEgetFrameNumber(void) 00183 { 00184 // Read current frame number 00185 uint16_t lowByte; 00186 uint16_t highByte; 00187 00188 SIECommand(SIE_CMD_READ_FRAME_NUMBER); 00189 lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00190 highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00191 00192 return (highByte << 8) | lowByte; 00193 } 00194 00195 static void SIEconfigureDevice(void) 00196 { 00197 // SIE Configure device command 00198 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00199 SIEWriteData(SIE_CONF_DEVICE); 00200 } 00201 00202 static void SIEunconfigureDevice(void) 00203 { 00204 // SIE Configure device command 00205 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00206 SIEWriteData(0); 00207 } 00208 00209 static void SIEconnect(void) 00210 { 00211 // Connect USB device 00212 uint8_t status; 00213 00214 status = SIEgetDeviceStatus(); 00215 SIEsetDeviceStatus(status | SIE_DS_CON); 00216 } 00217 00218 00219 static void SIEdisconnect(void) 00220 { 00221 // Disconnect USB device 00222 uint8_t status; 00223 00224 status = SIEgetDeviceStatus(); 00225 SIEsetDeviceStatus(status & ~SIE_DS_CON); 00226 } 00227 00228 00229 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) 00230 { 00231 // Implemented using using EP_INT_CLR. 00232 LPC_USB->USBEpIntClr = EP(endpoint); 00233 while (!(LPC_USB->USBDevIntSt & CDFULL)); 00234 return (uint8_t)LPC_USB->USBCmdData; 00235 } 00236 00237 00238 00239 00240 00241 static void enableEndpointEvent(uint8_t endpoint) 00242 { 00243 // Enable an endpoint interrupt 00244 LPC_USB->USBEpIntEn |= EP(endpoint); 00245 } 00246 00247 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused)); 00248 static void disableEndpointEvent(uint8_t endpoint) 00249 { 00250 // Disable an endpoint interrupt 00251 LPC_USB->USBEpIntEn &= ~EP(endpoint); 00252 } 00253 00254 static volatile uint32_t __attribute__((used)) dummyRead; 00255 00256 00257 static uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer) 00258 { 00259 // Read from an OUT endpoint 00260 uint32_t size; 00261 uint32_t i; 00262 uint32_t data = 0; 00263 uint8_t offset; 00264 00265 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN; 00266 while (!(LPC_USB->USBRxPLen & PKT_RDY)); 00267 00268 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK; 00269 00270 offset = 0; 00271 00272 if (size > 0) 00273 { 00274 for (i=0; i<size; i++) 00275 { 00276 if (offset==0) 00277 { 00278 // Fetch up to four bytes of data as a word 00279 data = LPC_USB->USBRxData; 00280 } 00281 00282 // extract a byte 00283 *buffer = (data>>offset) & 0xff; 00284 buffer++; 00285 00286 // move on to the next byte 00287 offset = (offset + 8) % 32; 00288 } 00289 } 00290 else 00291 { 00292 dummyRead = LPC_USB->USBRxData; 00293 } 00294 00295 SIEselectEndpoint(endpoint); 00296 SIEclearBuffer(); 00297 return size; 00298 } 00299 00300 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) 00301 { 00302 // Write to an IN endpoint 00303 uint32_t temp, data; 00304 uint8_t offset; 00305 00306 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN; 00307 00308 LPC_USB->USBTxPLen = size; 00309 offset = 0; 00310 data = 0; 00311 00312 if (size>0) 00313 { 00314 do { 00315 // Fetch next data byte into a word-sized temporary variable 00316 temp = *buffer++; 00317 00318 // Add to current data word 00319 temp = temp << offset; 00320 data = data | temp; 00321 00322 // move on to the next byte 00323 offset = (offset + 8) % 32; 00324 size--; 00325 00326 if ((offset==0) || (size==0)) 00327 { 00328 // Write the word to the endpoint 00329 LPC_USB->USBTxData = data; 00330 data = 0; 00331 } 00332 } while (size>0); 00333 } 00334 else 00335 { 00336 LPC_USB->USBTxData = 0; 00337 } 00338 00339 // Clear WR_EN to cover zero length packet case 00340 LPC_USB->USBCtrl=0; 00341 00342 SIEselectEndpoint(endpoint); 00343 SIEvalidateBuffer(); 00344 } 00345 00346 00347 00348 00349 00350 00351 00352 USBHAL::USBHAL(void) 00353 { 00354 // Disable IRQ 00355 NVIC_DisableIRQ(USB_IRQn); 00356 00357 // Enable power to USB device controller 00358 LPC_SC->PCONP |= PCUSB; 00359 00360 // Enable USB clocks 00361 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00362 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); 00363 00364 // Configure pins P0.29 and P0.30 to be USB D+ and USB D- 00365 LPC_PINCON->PINSEL1 &= 0xc3ffffff; 00366 LPC_PINCON->PINSEL1 |= 0x14000000; 00367 00368 // Disconnect USB device 00369 SIEdisconnect(); 00370 00371 // Configure pin P2.9 to be Connect 00372 LPC_PINCON->PINSEL4 &= 0xfffcffff; 00373 LPC_PINCON->PINSEL4 |= 0x00040000; 00374 00375 // Connect must be low for at least 2.5uS 00376 wait(0.3); 00377 00378 // Set the maximum packet size for the control endpoints 00379 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00380 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00381 00382 // Attach IRQ 00383 instance = this; 00384 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); 00385 NVIC_EnableIRQ(USB_IRQn); 00386 00387 // Enable interrupts for device events and EP0 00388 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT; 00389 enableEndpointEvent(EP0IN); 00390 enableEndpointEvent(EP0OUT); 00391 } 00392 00393 USBHAL::~USBHAL(void) 00394 { 00395 // Ensure device disconnected 00396 SIEdisconnect(); 00397 00398 // Disable USB interrupts 00399 NVIC_DisableIRQ(USB_IRQn); 00400 } 00401 00402 void USBHAL::connect(void) 00403 { 00404 // Connect USB device 00405 SIEconnect(); 00406 } 00407 00408 void USBHAL::disconnect(void) 00409 { 00410 // Disconnect USB device 00411 SIEdisconnect(); 00412 } 00413 00414 void USBHAL::configureDevice(void) 00415 { 00416 SIEconfigureDevice(); 00417 } 00418 00419 void USBHAL::unconfigureDevice(void) 00420 { 00421 SIEunconfigureDevice(); 00422 } 00423 00424 void USBHAL::setAddress(uint8_t address) 00425 { 00426 SIEsetAddress(address); 00427 } 00428 00429 void USBHAL::EP0setup(uint8_t *buffer) 00430 { 00431 endpointReadcore(EP0OUT, buffer); 00432 } 00433 00434 void USBHAL::EP0read(void) 00435 { 00436 // Not required 00437 } 00438 00439 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) 00440 { 00441 return endpointReadcore(EP0OUT, buffer); 00442 } 00443 00444 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) 00445 { 00446 endpointWritecore(EP0IN, buffer, size); 00447 } 00448 00449 void USBHAL::EP0getWriteResult(void) 00450 { 00451 // Not required 00452 } 00453 00454 void USBHAL::EP0stall(void) 00455 { 00456 // This will stall both control endpoints 00457 stallEndpoint(EP0OUT); 00458 } 00459 00460 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) 00461 { 00462 return EP_PENDING; 00463 } 00464 00465 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) 00466 { 00467 if(!(epComplete & EP(endpoint))) 00468 return EP_PENDING; 00469 *bytesRead = endpointReadcore(endpoint, buffer); 00470 epComplete &= ~EP(endpoint); 00471 return EP_COMPLETED; 00472 } 00473 00474 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) 00475 { 00476 if (getEndpointStallState(endpoint)) 00477 { 00478 return EP_STALLED; 00479 } 00480 00481 epComplete &= ~EP(endpoint); 00482 00483 endpointWritecore(endpoint, data, size); 00484 return EP_PENDING; 00485 } 00486 00487 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) 00488 { 00489 if (epComplete & EP(endpoint)) 00490 { 00491 epComplete &= ~EP(endpoint); 00492 return EP_COMPLETED; 00493 } 00494 00495 return EP_PENDING; 00496 } 00497 00498 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) 00499 { 00500 // Realise an endpoint 00501 LPC_USB->USBDevIntClr = EP_RLZED; 00502 LPC_USB->USBReEp |= EP(endpoint); 00503 LPC_USB->USBEpInd = endpoint; 00504 LPC_USB->USBMaxPSize = maxPacket; 00505 00506 while (!(LPC_USB->USBDevIntSt & EP_RLZED)); 00507 LPC_USB->USBDevIntClr = EP_RLZED; 00508 00509 // Clear stall state 00510 endpointStallState &= ~EP(endpoint); 00511 00512 enableEndpointEvent(endpoint); 00513 return true; 00514 } 00515 00516 void USBHAL::stallEndpoint(uint8_t endpoint) 00517 { 00518 // Stall an endpoint 00519 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) 00520 { 00521 // Conditionally stall both control endpoints 00522 SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST); 00523 } 00524 else 00525 { 00526 SIEsetEndpointStatus(endpoint, SIE_SES_ST); 00527 00528 // Update stall state 00529 endpointStallState |= EP(endpoint); 00530 } 00531 } 00532 00533 void USBHAL::unstallEndpoint(uint8_t endpoint) 00534 { 00535 // Unstall an endpoint. The endpoint will also be reinitialised 00536 SIEsetEndpointStatus(endpoint, 0); 00537 00538 // Update stall state 00539 endpointStallState &= ~EP(endpoint); 00540 } 00541 00542 bool USBHAL::getEndpointStallState(uint8_t endpoint) 00543 { 00544 // Returns true if endpoint stalled 00545 return endpointStallState & EP(endpoint); 00546 } 00547 00548 void USBHAL::remoteWakeup(void) 00549 { 00550 // Remote wakeup 00551 uint8_t status; 00552 00553 // Enable USB clocks 00554 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00555 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); 00556 00557 status = SIEgetDeviceStatus(); 00558 SIEsetDeviceStatus(status & ~SIE_DS_SUS); 00559 } 00560 00561 00562 00563 00564 00565 void USBHAL::_usbisr(void) 00566 { 00567 instance->usbisr(); 00568 } 00569 00570 DigitalOut ledd(LED1); 00571 void USBHAL::usbisr(void) 00572 { 00573 uint8_t devStat; 00574 00575 if (LPC_USB->USBDevIntSt & FRAME) 00576 { 00577 // Start of frame event 00578 SOF(SIEgetFrameNumber()); 00579 // Clear interrupt status flag 00580 LPC_USB->USBDevIntClr = FRAME; 00581 } 00582 00583 if (LPC_USB->USBDevIntSt & DEV_STAT) 00584 { 00585 // Device Status interrupt 00586 // Must clear the interrupt status flag before reading the device status from the SIE 00587 LPC_USB->USBDevIntClr = DEV_STAT; 00588 00589 // Read device status from SIE 00590 devStat = SIEgetDeviceStatus(); 00591 00592 if (devStat & SIE_DS_RST) 00593 { 00594 // Bus reset 00595 busReset(); 00596 } 00597 } 00598 00599 if (LPC_USB->USBDevIntSt & EP_SLOW) 00600 { 00601 // (Slow) Endpoint Interrupt 00602 00603 // Process each endpoint interrupt 00604 if (LPC_USB->USBEpIntSt & EP(EP0OUT)) 00605 { 00606 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) 00607 { 00608 // this is a setup packet 00609 EP0setupCallback(); 00610 } 00611 else 00612 { 00613 EP0out(); 00614 } 00615 LPC_USB->USBDevIntClr = EP_SLOW; 00616 } 00617 00618 if (LPC_USB->USBEpIntSt & EP(EP0IN)) 00619 { 00620 selectEndpointClearInterrupt(EP0IN); 00621 LPC_USB->USBDevIntClr = EP_SLOW; 00622 EP0in(); 00623 } 00624 00625 // TODO: This should cover all endpoints, not just EP1,2,3: 00626 if (LPC_USB->USBEpIntSt & EP(EP1IN)) 00627 { 00628 selectEndpointClearInterrupt(EP1IN); 00629 epComplete |= EP(EP1IN); 00630 LPC_USB->USBDevIntClr = EP_SLOW; 00631 } 00632 00633 if (LPC_USB->USBEpIntSt & EP(EP1OUT)) 00634 { 00635 selectEndpointClearInterrupt(EP1OUT); 00636 epComplete |= EP(EP1OUT); 00637 LPC_USB->USBDevIntClr = EP_SLOW; 00638 } 00639 00640 if (LPC_USB->USBEpIntSt & EP(EP2IN)) 00641 { 00642 ledd = 1; 00643 selectEndpointClearInterrupt(EP2IN); 00644 epComplete |= EP(EP2IN); 00645 LPC_USB->USBDevIntClr = EP_SLOW; 00646 if(EPBULK_IN_callback()) 00647 epComplete &= ~EP(EPBULK_OUT); 00648 } 00649 00650 if (LPC_USB->USBEpIntSt & EP(EP2OUT)) 00651 { 00652 selectEndpointClearInterrupt(EP2OUT); 00653 epComplete |= EP(EP2OUT); 00654 LPC_USB->USBDevIntClr = EP_SLOW; 00655 if(EPBULK_OUT_callback()) 00656 epComplete &= ~EP(EPBULK_OUT); 00657 } 00658 00659 if (LPC_USB->USBEpIntSt & EP(EP3IN)) 00660 { 00661 selectEndpointClearInterrupt(EP3IN); 00662 epComplete |= EP(EP3IN); 00663 LPC_USB->USBDevIntClr = EP_SLOW; 00664 } 00665 00666 if (LPC_USB->USBEpIntSt & EP(EP3OUT)) 00667 { 00668 selectEndpointClearInterrupt(EP3OUT); 00669 epComplete |= EP(EP3OUT); 00670 LPC_USB->USBDevIntClr = EP_SLOW; 00671 } 00672 } 00673 } 00674 00675 #endif
Generated on Tue Jul 12 2022 20:27:20 by 1.7.2