Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
USBHAL_M453.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2015-2016 Nuvoton 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #if defined(TARGET_NUMAKER_PFM_M453) 00018 00019 #include "USBHAL.h" 00020 #include "M451Series.h" 00021 #include "pinmap.h" 00022 00023 /** 00024 * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN. 00025 * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC. 00026 */ 00027 00028 USBHAL * USBHAL::instance; 00029 00030 /* Global variables for Control Pipe */ 00031 extern uint8_t g_usbd_SetupPacket[]; /*!< Setup packet buffer */ 00032 00033 static volatile uint32_t s_ep_compl = 0; 00034 static volatile uint32_t s_ep_buf_ind = 8; 00035 static volatile uint8_t s_usb_addr = 0; 00036 static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1}; 00037 static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0}; 00038 00039 extern volatile uint8_t *g_usbd_CtrlInPointer; 00040 extern volatile uint32_t g_usbd_CtrlInSize; 00041 extern volatile uint8_t *g_usbd_CtrlOutPointer; 00042 extern volatile uint32_t g_usbd_CtrlOutSize; 00043 extern volatile uint32_t g_usbd_CtrlOutSizeLimit; 00044 extern volatile uint32_t g_usbd_UsbConfig; 00045 extern volatile uint32_t g_usbd_CtrlMaxPktSize; 00046 extern volatile uint32_t g_usbd_UsbAltInterface; 00047 volatile uint32_t g_usbd_CepTransferLen = 0; 00048 volatile uint32_t frame_cnt = 0; 00049 USBHAL::USBHAL(void) 00050 { 00051 SYS_UnlockReg(); 00052 00053 s_ep_buf_ind = 8; 00054 00055 memset(epCallback, 0x00, sizeof (epCallback)); 00056 epCallback[0] = &USBHAL::EP1_OUT_callback; 00057 epCallback[1] = &USBHAL::EP2_IN_callback; 00058 epCallback[2] = &USBHAL::EP3_OUT_callback; 00059 epCallback[3] = &USBHAL::EP4_IN_callback; 00060 epCallback[4] = &USBHAL::EP5_OUT_callback; 00061 epCallback[5] = &USBHAL::EP6_IN_callback; 00062 00063 instance = this; 00064 /* Enable USBD module clock */ 00065 CLK_EnableModuleClock(USBD_MODULE); 00066 00067 CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV0_USB(3)); 00068 00069 /* Enable USB LDO33 */ 00070 SYS->USBPHY = SYS_USBPHY_LDO33EN_Msk; 00071 00072 /* Initial USB engine */ 00073 USBD->ATTR = 0x7D0; 00074 00075 /* Set SE0 (disconnect) */ 00076 USBD_SET_SE0(); 00077 00078 //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr); 00079 NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr); 00080 NVIC_EnableIRQ(USBD_IRQn); 00081 } 00082 00083 USBHAL::~USBHAL(void) 00084 { 00085 NVIC_DisableIRQ(USBD_IRQn); 00086 USBD_SET_SE0(); 00087 USBD_DISABLE_PHY(); 00088 } 00089 00090 void USBHAL::connect(void) 00091 { 00092 USBD->STBUFSEG = 0; 00093 frame_cnt = 0; 00094 /* EP0 ==> control IN endpoint, address 0 */ 00095 USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); 00096 /* Buffer range for EP0 */ 00097 USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind); 00098 00099 /* EP1 ==> control OUT endpoint, address 0 */ 00100 USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); 00101 /* Buffer range for EP1 */ 00102 USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind); 00103 00104 s_ep_buf_ind += MAX_PACKET_SIZE_EP0; 00105 00106 /* Disable software-disconnect function */ 00107 USBD_CLR_SE0(); 00108 00109 /* Clear USB-related interrupts before enable interrupt */ 00110 USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); 00111 00112 /* Enable USB-related interrupts. */ 00113 USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); 00114 } 00115 00116 void USBHAL::disconnect(void) 00117 { 00118 /* Set SE0 (disconnect) */ 00119 USBD_SET_SE0(); 00120 } 00121 00122 void USBHAL::configureDevice(void) 00123 { 00124 /** 00125 * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()). 00126 * So we have the following USB buffer management policy: 00127 * 1. Allocate for CEP on connect(). 00128 * 2. Allocate for EPX in realiseEndpoint(). 00129 * 3. Deallocate all except for CEP in unconfigureDevice(). 00130 */ 00131 } 00132 00133 void USBHAL::unconfigureDevice(void) 00134 { 00135 s_ep_buf_ind = 8; 00136 } 00137 00138 void USBHAL::setAddress(uint8_t address) 00139 { 00140 // NOTE: Delay address setting; otherwise, USB controller won't ack. 00141 s_usb_addr = address; 00142 } 00143 00144 void USBHAL::remoteWakeup(void) 00145 { 00146 #if 0 00147 USBD->OPER |= USBD_OPER_RESUMEEN_Msk; 00148 #endif 00149 } 00150 00151 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) 00152 { 00153 uint32_t ep_type = 0; 00154 uint32_t ep_hw_index = NU_EP2EPH(endpoint); 00155 uint32_t ep_logic_index = NU_EP2EPL(endpoint); 00156 uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; 00157 00158 if (ep_logic_index == 3 || ep_logic_index == 4) 00159 ep_type = USBD_CFG_TYPE_ISO; 00160 00161 USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index); 00162 /* Buffer range */ 00163 USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind); 00164 00165 if (ep_dir == USBD_CFG_EPMODE_OUT) 00166 USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket); 00167 00168 s_ep_mxp[ep_logic_index] = maxPacket; 00169 00170 s_ep_buf_ind += maxPacket; 00171 00172 return true; 00173 } 00174 00175 void USBHAL::EP0setup(uint8_t *buffer) 00176 { 00177 uint32_t sz; 00178 endpointReadResult(EP0OUT, buffer, &sz); 00179 } 00180 00181 void USBHAL::EP0read(void) 00182 { 00183 00184 00185 } 00186 00187 void USBHAL::EP0readStage(void) 00188 { 00189 // N/A 00190 00191 USBD_PrepareCtrlOut(0,0); 00192 } 00193 00194 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) 00195 { 00196 uint32_t i; 00197 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1)); 00198 uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1); 00199 for (i = 0; i < ceprxcnt; i ++) 00200 buffer[i] = buf[i]; 00201 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); 00202 return ceprxcnt; 00203 } 00204 00205 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) 00206 { 00207 if (buffer && size) 00208 { 00209 if (s_ep_data_bit[0] & 1) 00210 USBD_SET_DATA1(EP0); 00211 else 00212 USBD_SET_DATA0(EP0); 00213 s_ep_data_bit[0]++; 00214 00215 USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size); 00216 USBD_SET_PAYLOAD_LEN(EP0, size); 00217 if (size < MAX_PACKET_SIZE_EP0) 00218 s_ep_data_bit[0] = 1; 00219 00220 } 00221 else 00222 { 00223 if (g_usbd_SetupPacket[0] & 0x80) //Device to Host 00224 { 00225 // Status stage 00226 // USBD_PrepareCtrlOut(0,0); 00227 } else 00228 { 00229 USBD_SET_DATA1(EP0); 00230 USBD_SET_PAYLOAD_LEN(EP0, 0); 00231 } 00232 } 00233 } 00234 00235 void USBHAL::EP0getWriteResult(void) 00236 { 00237 // N/A 00238 } 00239 00240 void USBHAL::EP0stall(void) 00241 { 00242 stallEndpoint(EP0OUT); 00243 } 00244 00245 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) 00246 { 00247 return EP_PENDING; 00248 } 00249 00250 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng 00251 { 00252 if (endpoint == EP0OUT) 00253 { 00254 USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); 00255 if (buffer) { 00256 USBD_MemCopy(buffer, g_usbd_SetupPacket, 8); 00257 } 00258 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); 00259 } 00260 else 00261 { 00262 uint32_t i; 00263 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint))); 00264 uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint)); 00265 for (i = 0; i < eprxcnt; i ++) 00266 buffer[i] = buf[i]; 00267 00268 *bytesRead = eprxcnt; 00269 00270 USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]); 00271 } 00272 return EP_COMPLETED; 00273 } 00274 00275 00276 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) 00277 { 00278 return 0; 00279 } 00280 00281 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) 00282 { 00283 uint32_t ep_logic_index = NU_EP2EPL(endpoint); 00284 if (ep_logic_index == 0) 00285 return EP_INVALID; 00286 else 00287 { 00288 uint8_t *buf; 00289 uint32_t i=0; 00290 uint32_t ep_hw_index = NU_EP2EPH(endpoint); 00291 s_ep_compl |= (1 << ep_logic_index); 00292 buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index)); 00293 for (i=0;i<size;i++) 00294 buf[i] = data[i]; 00295 00296 /* Set transfer length and trigger IN transfer */ 00297 USBD_SET_PAYLOAD_LEN(ep_hw_index, size); 00298 00299 } 00300 return EP_PENDING; 00301 } 00302 00303 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) 00304 { 00305 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) 00306 return EP_COMPLETED; 00307 return EP_PENDING; 00308 } 00309 00310 void USBHAL::stallEndpoint(uint8_t endpoint) 00311 { 00312 uint32_t ep_hw_index = NU_EP2EPH(endpoint); 00313 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) 00314 return; 00315 00316 USBD_SetStall(NU_EPH2EPL(ep_hw_index)); 00317 00318 } 00319 00320 void USBHAL::unstallEndpoint(uint8_t endpoint) 00321 { 00322 uint32_t ep_hw_index = NU_EP2EPH(endpoint); 00323 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) 00324 return; 00325 USBD_ClearStall(NU_EPH2EPL(ep_hw_index)); 00326 } 00327 00328 bool USBHAL::getEndpointStallState(uint8_t endpoint) 00329 { 00330 uint32_t ep_hw_index = NU_EP2EPH(endpoint); 00331 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) 00332 return false; 00333 00334 return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0; 00335 } 00336 00337 void USBHAL::_usbisr(void) 00338 { 00339 MBED_ASSERT(instance); 00340 instance->usbisr(); 00341 } 00342 00343 void USBHAL::usbisr(void) 00344 { 00345 uint32_t u32IntSts = USBD_GET_INT_FLAG(); 00346 uint32_t u32State = USBD_GET_BUS_STATE(); 00347 00348 //------------------------------------------------------------------ 00349 if (u32IntSts & USBD_INTSTS_VBDETIF_Msk) 00350 { 00351 // Floating detect 00352 USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk); 00353 00354 if (USBD_IS_ATTACHED()) 00355 { 00356 /* USB Plug In */ 00357 USBD_ENABLE_USB(); 00358 } 00359 else 00360 { 00361 /* USB Un-plug */ 00362 USBD_DISABLE_USB(); 00363 } 00364 } 00365 00366 //------------------------------------------------------------------ 00367 if (u32IntSts & USBD_INTSTS_BUSIF_Msk) 00368 { 00369 /* Clear event flag */ 00370 USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk); 00371 00372 if (u32State & USBD_ATTR_USBRST_Msk) 00373 { 00374 /* Bus reset */ 00375 USBD_ENABLE_USB(); 00376 USBD_SwReset(); 00377 } 00378 if (u32State & USBD_ATTR_SUSPEND_Msk) 00379 { 00380 /* Enable USB but disable PHY */ 00381 USBD_DISABLE_PHY(); 00382 } 00383 if (u32State & USBD_ATTR_RESUME_Msk) 00384 { 00385 /* Enable USB and enable PHY */ 00386 USBD_ENABLE_USB(); 00387 } 00388 } 00389 00390 if (u32IntSts & USBD_INTSTS_USBIF_Msk) 00391 { 00392 // USB event 00393 if (u32IntSts & USBD_INTSTS_SETUP_Msk) 00394 { 00395 // Setup packet 00396 /* Clear event flag */ 00397 USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk); 00398 00399 /* Clear the data IN/OUT ready flag of control end-points */ 00400 USBD_STOP_TRANSACTION(EP0); 00401 USBD_STOP_TRANSACTION(EP1); 00402 EP0setupCallback(); 00403 } 00404 00405 // EP events 00406 if (u32IntSts & USBD_INTSTS_EP0) 00407 { 00408 /* Clear event flag */ 00409 USBD_CLR_INT_FLAG(USBD_INTSTS_EP0); 00410 // control IN 00411 EP0in(); 00412 00413 // In ACK for Set address 00414 if ((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) 00415 { 00416 if ((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0)) 00417 { 00418 USBD_SET_ADDR(s_usb_addr); 00419 } 00420 } 00421 } 00422 if (u32IntSts & USBD_INTSTS_EP1) 00423 { 00424 /* Clear event flag */ 00425 USBD_CLR_INT_FLAG(USBD_INTSTS_EP1); 00426 00427 // control OUT 00428 EP0out(); 00429 } 00430 00431 uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F; 00432 uint32_t ep_hw_index = 2; 00433 while (gintsts_epx) { 00434 if (gintsts_epx & 0x01) 00435 { 00436 uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7; 00437 /* Clear event flag */ 00438 USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16)); 00439 00440 if (ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3)) //RX 00441 { 00442 if (ep_status == 0x07) 00443 SOF(frame_cnt++); 00444 if ((instance->*(epCallback[ep_hw_index-2]))()) 00445 { 00446 00447 } 00448 USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]); 00449 } 00450 else if (ep_status == 0x00 || ep_status == 0x07) //TX 00451 { 00452 s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index))); 00453 if ((instance->*(epCallback[ep_hw_index-2]))()) 00454 { 00455 } 00456 } 00457 } 00458 00459 gintsts_epx = gintsts_epx >> 1; 00460 ep_hw_index++; 00461 } 00462 } 00463 } 00464 #endif 00465
Generated on Tue Jul 12 2022 11:02:58 by
1.7.2