diff --git a/features/unsupported/USBDevice/USBDevice/USBEndpoints.h b/features/unsupported/USBDevice/USBDevice/USBEndpoints.h index b9de9cd7bc..c04bd421ac 100644 --- a/features/unsupported/USBDevice/USBDevice/USBEndpoints.h +++ b/features/unsupported/USBDevice/USBDevice/USBEndpoints.h @@ -57,6 +57,8 @@ typedef enum { #include "USBEndpoints_NUC472.h" #elif defined(TARGET_NUMAKER_PFM_M453) #include "USBEndpoints_M453.h" +#elif defined(TARGET_M480) +#include "USBEndpoints_M480.h" #else #error "Unknown target type" #endif diff --git a/features/unsupported/USBDevice/USBDevice/USBHAL.h b/features/unsupported/USBDevice/USBDevice/USBHAL.h index 86f0786d9c..ef282e1cd3 100644 --- a/features/unsupported/USBDevice/USBDevice/USBHAL.h +++ b/features/unsupported/USBDevice/USBDevice/USBHAL.h @@ -132,7 +132,7 @@ private: bool (USBHAL::*epCallback[8 - 2])(void); #elif defined(TARGET_STM) PCD_HandleTypeDef hpcd; -#elif defined(TARGET_NUMAKER_PFM_NUC472) +#elif defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_M480) bool (USBHAL::*epCallback[14 - 2])(void); #else bool (USBHAL::*epCallback[32 - 2])(void); diff --git a/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h new file mode 100644 index 0000000000..221c229de3 --- /dev/null +++ b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h @@ -0,0 +1,93 @@ + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) +#define NU_MAX_EPX_BUFSIZE 4096 +#else +#define NU_MAX_EPX_BUFSIZE 4096 +#endif + +#define NU_EP2EPL(ep) ((ep) >> 1) + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) +#define NU_EP2EPH(ep) (((ep) >> 1) + 1) +#define NU_EPL2EPH(ep) ((ep) + 1) +#define NU_EPH2EPL(ep) ((ep) - 1) +#define NUMBER_OF_PHYSICAL_ENDPOINTS 8 +#else +#define NU_EP2EPH(ep) (((ep) >> 1) - 1) +#define NU_EPX2EP(ep) ((ep == CEP) ? EP0OUT : ((ep) - EPA + EP1OUT)) +#define NU_EPL2EPH(ep) ((ep) - 1) +#define NU_EPH2EPL(ep) ((ep) + 1) +#define NUMBER_OF_PHYSICAL_ENDPOINTS 12 +#endif + +#define NU_EP_DIR_Pos 0 +#define NU_EP_DIR_Msk (1 << NU_EP_DIR_Pos) +#define NU_EP_DIR_OUT 0 +#define NU_EP_DIR_IN 1 + +#define NU_EP_TYPE(ep) (((ep) & NU_EP_TYPE_Msk) >> NU_EP_TYPE_Pos) +#define NU_EP_NUM(ep) (((ep) & NU_EP_NUM_Msk) >> NU_EP_NUM_Pos) +#define NU_EP_DIR(ep) (((ep) & NU_EP_DIR_Msk) >> NU_EP_DIR_Pos) +#define NU_EP_NUM_DIR(ep) ((NU_EP_NUM(ep) << 1) | NU_EP_DIR(ep)) + +#define EP0OUT (0) +#define EP0IN (1) +#define EP1OUT (2) +#define EP1IN (3) +#define EP2OUT (4) +#define EP2IN (5) +#define EP3OUT (6) +#define EP3IN (7) +#define EP4OUT (8) +#define EP4IN (9) +#define EP5OUT (10) +#define EP5IN (11) +#define EP6OUT (12) +#define EP6IN (13) + +/* Maximum Packet sizes */ +#define MAX_PACKET_SIZE_EP0 64 +#define MAX_PACKET_SIZE_EP1 64 +#define MAX_PACKET_SIZE_EP2 64 +#define MAX_PACKET_SIZE_EP3 0x60 +#define MAX_PACKET_SIZE_EP4 64 +#define MAX_PACKET_SIZE_EP5 64 +#define MAX_PACKET_SIZE_EP6 64 +#define MAX_PACKET_SIZE_EP7 64 + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 1) +#define MAX_PACKET_SIZE_EP8 64 +#define MAX_PACKET_SIZE_EP9 64 +#define MAX_PACKET_SIZE_EP10 64 +#define MAX_PACKET_SIZE_EP11 64 +#endif + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoints */ +#define EPBULK_OUT EP5OUT +#define EPBULK_IN EP6IN +#define EPBULK_OUT_callback EP5_OUT_callback +#define EPBULK_IN_callback EP6_IN_callback +/* Interrupt endpoints */ +#define EPINT_OUT EP1OUT +#define EPINT_IN EP2IN +#define EPINT_OUT_callback EP1_OUT_callback +#define EPINT_IN_callback EP2_IN_callback +/* Isochronous endpoints */ +#define EPISO_OUT EP3OUT +#define EPISO_IN EP4IN +#define EPISO_OUT_callback EP3_OUT_callback +#define EPISO_IN_callback EP4_IN_callback + +#define MAX_PACKET_SIZE_EPBULK 64 +#define MAX_PACKET_SIZE_EPINT 64 +#define MAX_PACKET_SIZE_EPISO 1023 + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 1) +#define HSUSBD_GET_EP_MAX_PAYLOAD(ep) HSUSBD->EP[ep].EPMPS +#define HSUSBD_GET_EP_DATA_COUNT(ep) (HSUSBD->EP[ep].EPDATCNT & 0xFFFFF) +#define HSUSBD_SET_EP_SHORT_PACKET(ep) HSUSBD->EP[ep].EPRSPCTL = ((HSUSBD->EP[ep].EPRSPCTL & 0x10) | 0x40) +#define HSUSBD_GET_EP_INT_EN(ep) HSUSBD->EP[ep].EPINTEN +#endif diff --git a/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp new file mode 100644 index 0000000000..364d195db8 --- /dev/null +++ b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp @@ -0,0 +1,1093 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(TARGET_M480) + +#include "USBHAL.h" +#include "M480.h" +#include "pinmap.h" + +/** + * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN. + * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC. + */ + +USBHAL * USBHAL::instance; + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) + +/* Global variables for Control Pipe */ +extern uint8_t g_usbd_SetupPacket[]; /*!< Setup packet buffer */ + +static volatile uint32_t s_ep_compl = 0; +static volatile uint32_t s_ep_buf_ind = 8; +static volatile uint8_t s_usb_addr = 0; +static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1}; +static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0}; + +extern volatile uint8_t *g_usbd_CtrlInPointer; +extern volatile uint32_t g_usbd_CtrlInSize; +extern volatile uint8_t *g_usbd_CtrlOutPointer; +extern volatile uint32_t g_usbd_CtrlOutSize; +extern volatile uint32_t g_usbd_CtrlOutSizeLimit; +extern volatile uint32_t g_usbd_UsbConfig; +extern volatile uint32_t g_usbd_CtrlMaxPktSize; +extern volatile uint32_t g_usbd_UsbAltInterface; +volatile uint32_t g_usbd_CepTransferLen = 0; +volatile uint32_t frame_cnt = 0; + +USBHAL::USBHAL(void) +{ + SYS_UnlockReg(); + + s_ep_buf_ind = 8; + + memset(epCallback, 0x00, sizeof (epCallback)); + epCallback[0] = &USBHAL::EP1_OUT_callback; + epCallback[1] = &USBHAL::EP2_IN_callback; + epCallback[2] = &USBHAL::EP3_OUT_callback; + epCallback[3] = &USBHAL::EP4_IN_callback; + epCallback[4] = &USBHAL::EP5_OUT_callback; + epCallback[5] = &USBHAL::EP6_IN_callback; + epCallback[6] = &USBHAL::EP7_OUT_callback; + epCallback[7] = &USBHAL::EP8_IN_callback; + epCallback[8] = &USBHAL::EP9_OUT_callback; + epCallback[9] = &USBHAL::EP10_IN_callback; + epCallback[10] = &USBHAL::EP11_OUT_callback; + epCallback[11] = &USBHAL::EP12_IN_callback; + + instance = this; + + /* Configure USB to Device mode */ + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_USBROLE_STD_USBD; + + /* Enable USB PHY */ + SYS->USBPHY |= SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk; + + /* Select IP clock source */ + CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | CLK_CLKDIV0_USB(4); + + /* Enable IP clock */ + CLK_EnableModuleClock(USBD_MODULE); + + /* Configure pins for USB 1.1 port: VBUS/D+/D-/ID */ + pin_function(PA_12, SYS_GPA_MFPH_PA12MFP_USB_VBUS); + pin_function(PA_13, SYS_GPA_MFPH_PA13MFP_USB_D_N); + pin_function(PA_14, SYS_GPA_MFPH_PA14MFP_USB_D_P); + pin_function(PA_15, (int) SYS_GPA_MFPH_PA15MFP_USB_OTG_ID); + + /* Initial USB engine */ + USBD->ATTR = 0x7D0; + + /* Set SE0 (disconnect) */ + USBD_SET_SE0(); + + //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr); + NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr); + NVIC_EnableIRQ(USBD_IRQn); +} + +USBHAL::~USBHAL(void) +{ + NVIC_DisableIRQ(USBD_IRQn); + USBD_SET_SE0(); + USBD_DISABLE_PHY(); +} + +void USBHAL::connect(void) +{ + USBD->STBUFSEG = 0; + frame_cnt = 0; + /* EP0 ==> control IN endpoint, address 0 */ + USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); + /* Buffer range for EP0 */ + USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind); + + /* EP1 ==> control OUT endpoint, address 0 */ + USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); + /* Buffer range for EP1 */ + USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind); + + s_ep_buf_ind += MAX_PACKET_SIZE_EP0; + + /* Disable software-disconnect function */ + USBD_CLR_SE0(); + + /* Clear USB-related interrupts before enable interrupt */ + USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); + + /* Enable USB-related interrupts. */ + USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); +} + +void USBHAL::disconnect(void) +{ + /* Set SE0 (disconnect) */ + USBD_SET_SE0(); +} + +void USBHAL::configureDevice(void) +{ + /** + * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()). + * So we have the following USB buffer management policy: + * 1. Allocate for CEP on connect(). + * 2. Allocate for EPX in realiseEndpoint(). + * 3. Deallocate all except for CEP in unconfigureDevice(). + */ +} + +void USBHAL::unconfigureDevice(void) +{ + s_ep_buf_ind = 8; +} + +void USBHAL::setAddress(uint8_t address) +{ + // NOTE: Delay address setting; otherwise, USB controller won't ack. + s_usb_addr = address; +} + +void USBHAL::remoteWakeup(void) +{ +#if 0 + USBD->OPER |= USBD_OPER_RESUMEEN_Msk; +#endif +} + +bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) +{ + uint32_t ep_type = 0; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; + + if(ep_logic_index == 3 || ep_logic_index == 4) + ep_type = USBD_CFG_TYPE_ISO; + + USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index); + /* Buffer range */ + USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind); + + if(ep_dir == USBD_CFG_EPMODE_OUT) + USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket); + + s_ep_mxp[ep_logic_index] = maxPacket; + + s_ep_buf_ind += maxPacket; + + return true; +} + +void USBHAL::EP0setup(uint8_t *buffer) +{ + uint32_t sz; + endpointReadResult(EP0OUT, buffer, &sz); +} + +void USBHAL::EP0read(void) +{ + + +} + +void USBHAL::EP0readStage(void) +{ + // N/A + + USBD_PrepareCtrlOut(0,0); +} + +uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) +{ + uint32_t i; + uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1)); + uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1); + for (i = 0; i < ceprxcnt; i ++) + buffer[i] = buf[i]; + USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); + return ceprxcnt; +} + +void USBHAL::EP0write(uint8_t *buffer, uint32_t size) +{ + if (buffer && size) { + if(s_ep_data_bit[0] & 1) + USBD_SET_DATA1(EP0); + else + USBD_SET_DATA0(EP0); + s_ep_data_bit[0]++; + + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size); + USBD_SET_PAYLOAD_LEN(EP0, size); + if(size < MAX_PACKET_SIZE_EP0) + s_ep_data_bit[0] = 1; + + } else { + if(g_usbd_SetupPacket[0] & 0x80) { //Device to Host + // Status stage + // USBD_PrepareCtrlOut(0,0); + } else { + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + } + } +} + +void USBHAL::EP0getWriteResult(void) +{ + // N/A +} + +void USBHAL::EP0stall(void) +{ + stallEndpoint(EP0OUT); +} + +EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) +{ + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng +{ + if(endpoint == EP0OUT) { + USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); + if (buffer) { + USBD_MemCopy(buffer, g_usbd_SetupPacket, 8); + } + USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); + } else { + uint32_t i; + uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint))); + uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint)); + for (i = 0; i < eprxcnt; i ++) + buffer[i] = buf[i]; + + *bytesRead = eprxcnt; + + USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]); + } + return EP_COMPLETED; +} + + +uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) +{ + return 0; +} + +EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) +{ + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + if(ep_logic_index == 0) + return EP_INVALID; + else { + uint8_t *buf; + uint32_t i=0; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + s_ep_compl |= (1 << ep_logic_index); + buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index)); + for(i=0; i= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + + USBD_SetStall(NU_EPH2EPL(ep_hw_index)); + +} + +void USBHAL::unstallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + USBD_ClearStall(NU_EPH2EPL(ep_hw_index)); +} + +bool USBHAL::getEndpointStallState(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return false; + + return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0; +} + +void USBHAL::_usbisr(void) +{ + MBED_ASSERT(instance); + instance->usbisr(); +} + +void USBHAL::usbisr(void) +{ + uint32_t u32IntSts = USBD_GET_INT_FLAG(); + uint32_t u32State = USBD_GET_BUS_STATE(); + +//------------------------------------------------------------------ + if(u32IntSts & USBD_INTSTS_VBDETIF_Msk) { + // Floating detect + USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk); + + if(USBD_IS_ATTACHED()) { + /* USB Plug In */ + USBD_ENABLE_USB(); + } else { + /* USB Un-plug */ + USBD_DISABLE_USB(); + } + } + +//------------------------------------------------------------------ + if(u32IntSts & USBD_INTSTS_BUSIF_Msk) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk); + + if(u32State & USBD_ATTR_USBRST_Msk) { + /* Bus reset */ + USBD_ENABLE_USB(); + USBD_SwReset(); + } + if(u32State & USBD_ATTR_SUSPEND_Msk) { + /* Enable USB but disable PHY */ + USBD_DISABLE_PHY(); + } + if(u32State & USBD_ATTR_RESUME_Msk) { + /* Enable USB and enable PHY */ + USBD_ENABLE_USB(); + } + } + + if(u32IntSts & USBD_INTSTS_USBIF_Msk) { + // USB event + if(u32IntSts & USBD_INTSTS_SETUP_Msk) { + // Setup packet + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk); + + /* Clear the data IN/OUT ready flag of control end-points */ + USBD_STOP_TRANSACTION(EP0); + USBD_STOP_TRANSACTION(EP1); + EP0setupCallback(); + } + + // EP events + if(u32IntSts & USBD_INTSTS_EP0) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_EP0); + // control IN + EP0in(); + + // In ACK for Set address + if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) { + if((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0)) { + USBD_SET_ADDR(s_usb_addr); + } + } + } + if(u32IntSts & USBD_INTSTS_EP1) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_EP1); + + // control OUT + EP0out(); + } + + uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F; + uint32_t ep_hw_index = 2; + while (gintsts_epx) { + if(gintsts_epx & 0x01) { + uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7; + /* Clear event flag */ + USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16)); + + if(ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3)) { //RX + if(ep_status == 0x07) + SOF(frame_cnt++); + if ((instance->*(epCallback[ep_hw_index-2]))()) { + + } + USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]); + } else if(ep_status == 0x00 || ep_status == 0x07) { //TX + s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index))); + if ((instance->*(epCallback[ep_hw_index-2]))()) { + } + } + } + + gintsts_epx = gintsts_epx >> 1; + ep_hw_index++; + } + } +} +#else + +static volatile uint32_t s_ep_compl = 0; +static volatile uint32_t s_ep_buf_ind = 0; +static volatile uint8_t s_usb_addr = 0; +static volatile S_HSUSBD_CMD_T s_setup; +static volatile uint16_t s_ctrlin_packetsize; +static uint8_t *g_usbd_CtrlInPointer = 0; +static uint32_t g_usbd_CtrlMaxPktSize = 64; +static volatile uint32_t g_usbd_CtrlInSize; +static uint32_t g_usbd_ShortPacket = 0; +//static uint32_t gEpRead = 0; +static uint32_t gEpReadCnt = 0; + +void HSUSBD_CtrlInput(void) +{ + unsigned volatile i; + uint32_t volatile count; + + // Process remained data + if(g_usbd_CtrlInSize >= g_usbd_CtrlMaxPktSize) { + // Data size > MXPLD + for (i=0; i<(g_usbd_CtrlMaxPktSize >> 2); i++, g_usbd_CtrlInPointer+=4) + HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer; + HSUSBD_START_CEP_IN(g_usbd_CtrlMaxPktSize); + g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; + } else { + // Data size <= MXPLD + for (i=0; i<(g_usbd_CtrlInSize >> 2); i++, g_usbd_CtrlInPointer+=4) + HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer; + + count = g_usbd_CtrlInSize % 4; + for (i=0; iCEPDAT_BYTE = *(uint8_t *)(g_usbd_CtrlInPointer + i); + + HSUSBD_START_CEP_IN(g_usbd_CtrlInSize); + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + } +} + +USBHAL::USBHAL(void) +{ + SYS_UnlockReg(); + + s_ep_buf_ind = 0; + + memset(epCallback, 0x00, sizeof (epCallback)); + epCallback[0] = &USBHAL::EP1_OUT_callback; + epCallback[1] = &USBHAL::EP2_IN_callback; + epCallback[2] = &USBHAL::EP3_OUT_callback; + epCallback[3] = &USBHAL::EP4_IN_callback; + epCallback[4] = &USBHAL::EP5_OUT_callback; + epCallback[5] = &USBHAL::EP6_IN_callback; + epCallback[6] = &USBHAL::EP7_OUT_callback; + epCallback[7] = &USBHAL::EP8_IN_callback; + epCallback[8] = &USBHAL::EP9_OUT_callback; + epCallback[9] = &USBHAL::EP10_IN_callback; + epCallback[10] = &USBHAL::EP11_OUT_callback; + epCallback[11] = &USBHAL::EP12_IN_callback; + + instance = this; + + /* Configure HSUSB to Device mode */ + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_HSUSBROLE_Msk) | SYS_USBPHY_HSUSBROLE_STD_USBD; + /* Enable HSUSB PHY */ + SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_HSUSBACT_Msk)) | SYS_USBPHY_HSUSBEN_Msk; + /* Delay >10 us and then switch HSUSB PHY from reset state to active state */ + wait_us(10); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; + + /* Enable USBD module clock */ + CLK_EnableModuleClock(HSUSBD_MODULE); + + /* Enable USB PHY and wait for it ready */ + HSUSBD_ENABLE_PHY(); + while (1) { + HSUSBD->EP[0].EPMPS = 0x20; + if (HSUSBD->EP[0].EPMPS == 0x20) + break; + } + + /* Force to full-speed */ + HSUSBD->OPER = 0;//USBD_OPER_HISPDEN_Msk; + + /* Set SE0 (disconnect) */ + HSUSBD_SET_SE0(); + + NVIC_SetVector(USBD20_IRQn, (uint32_t) &_usbisr); + NVIC_EnableIRQ(USBD20_IRQn); +} + +USBHAL::~USBHAL(void) +{ + NVIC_DisableIRQ(USBD20_IRQn); + HSUSBD_SET_SE0(); + HSUSBD_DISABLE_PHY(); +} + +void USBHAL::connect(void) +{ + HSUSBD_ResetDMA(); + HSUSBD_SET_ADDR(0); + + /** + * Control Transfer Packet Size Constraints + * low-speed: 8 + * full-speed: 8, 16, 32, 64 + * high-speed: 64 + */ + /* Control endpoint */ + HSUSBD_SetEpBufAddr(CEP, s_ep_buf_ind, MAX_PACKET_SIZE_EP0); + s_ep_buf_ind = MAX_PACKET_SIZE_EP0; + + /* Enable USB/CEP interrupt */ + HSUSBD_ENABLE_USB_INT(HSUSBD_GINTEN_USBIEN_Msk | HSUSBD_GINTEN_CEPIEN_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk); + + /* Enable BUS interrupt */ + HSUSBD_ENABLE_BUS_INT( + HSUSBD_BUSINTEN_DMADONEIEN_Msk | + HSUSBD_BUSINTEN_RESUMEIEN_Msk | + HSUSBD_BUSINTEN_RSTIEN_Msk | + HSUSBD_BUSINTEN_VBUSDETIEN_Msk | + HSUSBD_BUSINTEN_SOFIEN_Msk + ); + + /* Clear SE0 (connect) */ + HSUSBD_CLR_SE0(); +} + +void USBHAL::disconnect(void) +{ + /* Set SE0 (disconnect) */ + HSUSBD_SET_SE0(); +} + +void USBHAL::configureDevice(void) +{ + /** + * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()). + * So we have the following USB buffer management policy: + * 1. Allocate for CEP on connect(). + * 2. Allocate for EPX in realiseEndpoint(). + * 3. Deallocate all except for CEP in unconfigureDevice(). + */ +} + +void USBHAL::unconfigureDevice(void) +{ + s_ep_buf_ind = MAX_PACKET_SIZE_EP0; +} + +void USBHAL::setAddress(uint8_t address) +{ + // NOTE: Delay address setting; otherwise, USB controller won't ack. + s_usb_addr = address; +} + +void USBHAL::remoteWakeup(void) +{ + HSUSBD->OPER |= HSUSBD_OPER_RESUMEEN_Msk; +} + +bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) +{ + uint32_t ep_type; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + + HSUSBD_SetEpBufAddr(ep_hw_index, s_ep_buf_ind, maxPacket); + s_ep_buf_ind += maxPacket; + HSUSBD_SET_MAX_PAYLOAD(ep_hw_index, maxPacket); + + switch (NU_EP2EPL(endpoint)) { + case 1: + case 2: + ep_type = HSUSBD_EP_CFG_TYPE_INT; + break; + + case 3: + case 4: + ep_type = HSUSBD_EP_CFG_TYPE_ISO; + break; + + default: + ep_type = HSUSBD_EP_CFG_TYPE_BULK; + } + uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? HSUSBD_EP_CFG_DIR_IN : HSUSBD_EP_CFG_DIR_OUT; + HSUSBD_ConfigEp(ep_hw_index, NU_EP2EPL(endpoint), ep_type, ep_dir); + + /* Enable USB/EPX interrupt */ + // NOTE: Require USBD_GINTEN_EPAIE_Pos, USBD_GINTEN_EPBIE_Pos, ... USBD_GINTEN_EPLIE_Pos to be consecutive. + HSUSBD_ENABLE_USB_INT(HSUSBD->GINTEN | HSUSBD_GINTEN_USBIEN_Msk | + HSUSBD_GINTEN_CEPIEN_Msk | + 1 << (ep_hw_index + HSUSBD_GINTEN_EPAIEN_Pos)); // Added USB/EPX interrupt + + if (ep_dir == 0) + HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_RXPKIEN_Msk); + else + HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_TXPKIEN_Msk); + return true; +} + +void USBHAL::EP0setup(uint8_t *buffer) +{ + uint32_t sz; + endpointReadResult(EP0OUT, buffer, &sz); +} + +void USBHAL::EP0read(void) +{ + if (s_setup.wLength && ! (s_setup.bmRequestType & 0x80)) { + // Control OUT + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk | HSUSBD_CEPINTEN_RXPKIEN_Msk); + } else { + // Status stage + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } +} + +void USBHAL::EP0readStage(void) +{ + // N/A +} + +uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) +{ + uint32_t i; + uint32_t ceprxcnt = HSUSBD->CEPRXCNT; + for (i = 0; i < ceprxcnt; i ++) + *buffer ++ = HSUSBD->CEPDAT_BYTE; + return ceprxcnt; +} + +void USBHAL::EP0write(uint8_t *buffer, uint32_t size) +{ + if (buffer && size) { + g_usbd_CtrlInPointer = buffer; + g_usbd_CtrlInSize = size; + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); + } else { + /* Status stage */ + s_ctrlin_packetsize = 0; + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } +} + +void USBHAL::EP0getWriteResult(void) +{ + // N/A +} + +void USBHAL::EP0stall(void) +{ + stallEndpoint(EP0OUT); +} + +EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) +{ + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng +{ + if(endpoint == EP0OUT) { + if (buffer) { + *((uint16_t *) (buffer + 0)) = (uint16_t) HSUSBD->SETUP1_0; + *((uint16_t *) (buffer + 2)) = (uint16_t) HSUSBD->SETUP3_2; + *((uint16_t *) (buffer + 4)) = (uint16_t) HSUSBD->SETUP5_4; + *((uint16_t *) (buffer + 6)) = (uint16_t) HSUSBD->SETUP7_6; + } + + s_setup.bmRequestType = (uint8_t) (HSUSBD->SETUP1_0 & 0xff); + s_setup.bRequest = (int8_t) (HSUSBD->SETUP1_0 >> 8) & 0xff; + s_setup.wValue = (uint16_t) HSUSBD->SETUP3_2; + s_setup.wIndex = (uint16_t) HSUSBD->SETUP5_4; + s_setup.wLength = (uint16_t) HSUSBD->SETUP7_6; + } else { + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) { + while(1) { + if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + break; + else if (!HSUSBD_IS_ATTACHED()) + break; + } + gEpReadCnt = HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint)); + if(gEpReadCnt == 0) { + *bytesRead = 0; + return EP_COMPLETED; + } + s_ep_compl |= (1 << NU_EP2EPL(endpoint)); + HSUSBD_SET_DMA_LEN(gEpReadCnt); + HSUSBD_SET_DMA_ADDR((uint32_t)buffer); + HSUSBD_SET_DMA_WRITE(NU_EP2EPL(endpoint)); + HSUSBD_ENABLE_DMA(); + return EP_PENDING;; + + } else { + if ((HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + return EP_PENDING;; + + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk); + s_ep_compl &= ~(1 << NU_EP2EPL(endpoint)); + *bytesRead = gEpReadCnt; + } + } + return EP_COMPLETED; +} + + +uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) +{ + return 0; +} + +EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) +{ + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + if(ep_logic_index == 0) + return EP_INVALID; + else { + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + uint32_t mps = HSUSBD_GET_EP_MAX_PAYLOAD(ep_hw_index); + if (size > mps) { + return EP_INVALID; + } + if(size < mps) + g_usbd_ShortPacket = 1; + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) { + s_ep_compl |= (1 << ep_logic_index); + + while(1) { + if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + break; + else if (!HSUSBD_IS_ATTACHED()) + break; + } + HSUSBD_SET_DMA_LEN(size); + HSUSBD_SET_DMA_ADDR((uint32_t)data); + HSUSBD_SET_DMA_READ(ep_logic_index); + HSUSBD_ENABLE_DMA(); + } + } + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) +{ + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) + return EP_COMPLETED; + else { + if((HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint))) == 0 && !(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) { + s_ep_compl &= ~(s_ep_compl & (1 << NU_EP2EPL(endpoint))); + return EP_COMPLETED; + } + } + return EP_PENDING; +} + +void USBHAL::stallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + HSUSBD_SetStall(ep_hw_index); +} + +void USBHAL::unstallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + HSUSBD_ClearStall(ep_hw_index); +} + +bool USBHAL::getEndpointStallState(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return false; + return HSUSBD_GetStall(ep_hw_index) ? 1 : 0; +} + +void USBHAL::_usbisr(void) +{ + MBED_ASSERT(instance); + instance->usbisr(); +} + +void USBHAL::usbisr(void) +{ + uint32_t gintsts = HSUSBD->GINTSTS & HSUSBD->GINTEN; + if (! gintsts) + return; + + if (gintsts & HSUSBD_GINTSTS_USBIF_Msk) { + uint32_t busintsts = HSUSBD->BUSINTSTS & HSUSBD->BUSINTEN; + + /* SOF */ + if (busintsts & HSUSBD_BUSINTSTS_SOFIF_Msk) { + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SOFIF_Msk); + // TODO + SOF(HSUSBD->FRAMECNT >> 3); + } + + /* Reset */ + if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) { + connect(); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RSTIF_Msk); + HSUSBD_CLR_CEP_INT_FLAG(0x1ffc); + } + + /* Resume */ + if (busintsts & HSUSBD_BUSINTSTS_RESUMEIF_Msk) { + HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk|HSUSBD_BUSINTEN_SUSPENDIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RESUMEIF_Msk); + } + + /* Suspend */ + if (busintsts & HSUSBD_BUSINTSTS_SUSPENDIF_Msk) { + HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk | HSUSBD_BUSINTEN_RESUMEIEN_Msk |HSUSBD_BUSINTEN_SOFIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SUSPENDIF_Msk); + } + + /* High-speed */ + if (busintsts & HSUSBD_BUSINTSTS_HISPDIF_Msk) { + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_HISPDIF_Msk); + } + + /* DMA */ + if (busintsts & HSUSBD_BUSINTSTS_DMADONEIF_Msk) { + if(HSUSBD->DMACTL & 0x10) { /* IN - Read */ + if(g_usbd_ShortPacket) { + uint32_t ep_hw_index = NU_EPL2EPH((HSUSBD->DMACTL & 0xF)); + HSUSBD_SET_EP_SHORT_PACKET(ep_hw_index); + g_usbd_ShortPacket = 0; + } + } + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk); + } + + /* PHY clock available */ + if (busintsts & HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk) { + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk); + } + + /* VBUS plug-in */ + if (busintsts & HSUSBD_BUSINTSTS_VBUSDETIF_Msk) { + if (HSUSBD_IS_ATTACHED()) { + // USB plug-in + HSUSBD_ENABLE_USB(); + } else { + // USB unplug-out + HSUSBD_DISABLE_USB(); + } + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_VBUSDETIF_Msk); + } + } + + /* CEP interrupts */ + if (gintsts & HSUSBD_GINTSTS_CEPIF_Msk) { + uint32_t cepintsts = HSUSBD->CEPINTSTS & HSUSBD->CEPINTEN; + + /* SETUP token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPTKIF_Msk); + return; + } + + /* SETUP transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPPKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk); + EP0setupCallback(); + return; + } + + /* OUT token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_OUTTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_OUTTKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + return; + } + + /* IN token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_INTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); + if (!(cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk)) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk); + HSUSBD_CtrlInput(); + } else { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } + return; + } + + /* PING packet */ + if (cepintsts & HSUSBD_CEPINTSTS_PINGIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_PINGIF_Msk); + return; + } + + /* IN transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_TXPKIF_Msk) { + EP0in(); + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + return; + } + + /* OUT transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_RXPKIF_Msk) { + EP0out(); + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_RXPKIF_Msk); + return; + } + + /* NAK handshake packet */ + if (cepintsts & HSUSBD_CEPINTSTS_NAKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_NAKIF_Msk); + return; + } + + /* STALL handshake packet */ + if (cepintsts & HSUSBD_CEPINTSTS_STALLIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STALLIF_Msk); + return; + } + + /* ERR special packet */ + if (cepintsts & HSUSBD_CEPINTSTS_ERRIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_ERRIF_Msk); + return; + } + + /* Status stage transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk) { + if (s_usb_addr) { + HSUSBD_SET_ADDR(s_usb_addr); + s_usb_addr = 0; + } + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk); + return; + } + + /* Buffer Full */ + if (cepintsts & HSUSBD_CEPINTSTS_BUFFULLIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFFULLIF_Msk); + return; + } + + /* Buffer Empty */ + if (cepintsts & HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk); + return; + } + } + /* EPA, EPB, EPC, ... EPL interrupts */ + uint32_t gintsts_epx = gintsts >> 2; + uint32_t ep_hw_index = 0; + while (gintsts_epx) { + if(gintsts_epx & 0x01) { + uint32_t epxintsts = HSUSBD_GET_EP_INT_FLAG(ep_hw_index) & HSUSBD_GET_EP_INT_EN(ep_hw_index); + + HSUSBD_CLR_EP_INT_FLAG(ep_hw_index, epxintsts); + + /* Buffer Full */ + if (epxintsts & HSUSBD_EPINTSTS_BUFFULLIF_Msk) { + } + + /* Buffer Empty */ + if (epxintsts & HSUSBD_EPINTSTS_BUFEMPTYIF_Msk) { + } + + /* Short Packet Transferred */ + if (epxintsts & HSUSBD_EPINTSTS_SHORTTXIF_Msk) { + } + + /* Data Packet Transmitted */ + if (epxintsts & HSUSBD_EPINTSTS_TXPKIF_Msk) { + s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index))); + if ((instance->*(epCallback[ep_hw_index]))()) { + } + } + + /* Data Packet Received */ + if (epxintsts & HSUSBD_EPINTSTS_RXPKIF_Msk) { + if ((instance->*(epCallback[ep_hw_index]))()) { + + } + } + + /* OUT token packet */ + if (epxintsts & HSUSBD_EPINTSTS_OUTTKIF_Msk) { + } + + /* IN token packet */ + if (epxintsts & HSUSBD_EPINTSTS_INTKIF_Msk) { + } + + /* PING packet */ + if (epxintsts & HSUSBD_EPINTSTS_PINGIF_Msk) { + } + + /* NAK handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_NAKIF_Msk) { + } + + /* STALL handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_STALLIF_Msk) { + } + + /* NYET handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_NYETIF_Msk) { + } + + /* ERR packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_ERRIF_Msk) { + } + + /* Bulk Out Short Packet Received */ + if (epxintsts & HSUSBD_EPINTSTS_SHORTRXIF_Msk) { + } + } + gintsts_epx = gintsts_epx >> 1; + ep_hw_index++; + } +} +#endif + +#endif + diff --git a/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp b/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp new file mode 100644 index 0000000000..37ecdafda6 --- /dev/null +++ b/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp @@ -0,0 +1,427 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(TARGET_M480) + +#include "mbed.h" +#include "USBHALHost.h" +#include "dbg.h" +#include "pinmap.h" + +#define HCCA_SIZE sizeof(HCCA) +#define ED_SIZE sizeof(HCED) +#define TD_SIZE sizeof(HCTD) + +#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE)) +#ifndef USBH_HcRhDescriptorA_POTPGT_Pos +#define USBH_HcRhDescriptorA_POTPGT_Pos (24) +#endif +#ifndef USBH_HcRhDescriptorA_POTPGT_Msk +#define USBH_HcRhDescriptorA_POTPGT_Msk (0xfful << USBH_HcRhDescriptorA_POTPGT_Pos) +#endif + +static volatile MBED_ALIGN(256) uint8_t usb_buf[TOTAL_SIZE]; // 256 bytes aligned! + +USBHALHost * USBHALHost::instHost; + +USBHALHost::USBHALHost() +{ + instHost = this; + memInit(); + memset((void*)usb_hcca, 0, HCCA_SIZE); + for (int i = 0; i < MAX_ENDPOINT; i++) { + edBufAlloc[i] = false; + } + for (int i = 0; i < MAX_TD; i++) { + tdBufAlloc[i] = false; + } +} + +void USBHALHost::init() +{ + // Unlock protected registers + SYS_UnlockReg(); + + /* Enable IP clock */ + CLK->AHBCLK |= CLK_AHBCLK_USBHCKEN_Msk | (1 << 4) | CLK_AHBCLK_HSUSBDCKEN_Msk; + + + /* USB Host desired input clock is 48 MHz. Set as PLL divided by 4 (192/4 = 48) */ + CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | (3 << CLK_CLKDIV0_USBDIV_Pos); + + /* Enable USBD and OTG clock */ + CLK->APBCLK0 |= CLK_APBCLK0_USBDCKEN_Msk | CLK_APBCLK0_OTGCKEN_Msk; + + /* Configure USB to USB Host role */ + SYS->USBPHY = SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_HSUSBROLE_STD_USBH | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk | SYS_USBPHY_USBROLE_STD_USBH; + + wait_us(20); + + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; + + /*---------------------------------------------------------------------------------------------------------*/ + /* Init I/O Multi-function */ + /*---------------------------------------------------------------------------------------------------------*/ + + + /* USB_VBUS_EN (USB 1.1 VBUS power enable pin) multi-function pin - PB.15 */ + pin_function(PB_15, SYS_GPB_MFPH_PB15MFP_USB_VBUS_EN); + + /* USB_VBUS_ST (USB 1.1 over-current detect pin) multi-function pin - PC.14 */ + pin_function(PC_14, SYS_GPC_MFPH_PC14MFP_USB_VBUS_ST); + + /* HSUSB_VBUS_EN (USB 2.0 VBUS power enable pin) multi-function pin - PB.10 */ + pin_function(PB_10, SYS_GPB_MFPH_PB10MFP_HSUSB_VBUS_EN); + + /* HSUSB_VBUS_ST (USB 2.0 over-current detect pin) multi-function pin - PB.11 */ + pin_function(PB_11, SYS_GPB_MFPH_PB11MFP_HSUSB_VBUS_ST); + + /* Configure pins for USB 1.1 port: VBUS/D+/D-/ID */ + pin_function(PA_12, SYS_GPA_MFPH_PA12MFP_USB_VBUS); + pin_function(PA_13, SYS_GPA_MFPH_PA13MFP_USB_D_N); + pin_function(PA_14, SYS_GPA_MFPH_PA14MFP_USB_D_P); + pin_function(PA_15, (int) SYS_GPA_MFPH_PA15MFP_USB_OTG_ID); + + SYS_LockReg(); + HSUSBH->USBPCR0 = 0x160; /* enable PHY 0 */ + HSUSBH->USBPCR1 = 0x520; /* enable PHY 1 */ + + // Overcurrent flag is low active + USBH->HcMiscControl |= USBH_HcMiscControl_OCAL_Msk; + + // Disable HC interrupts + USBH->HcInterruptDisable = OR_INTR_ENABLE_MIE; + + // Needed by some controllers + USBH->HcControl = 0; + + // Software reset + USBH->HcCommandStatus = OR_CMD_STATUS_HCR; + while (USBH->HcCommandStatus & OR_CMD_STATUS_HCR); + + // Put HC in reset state + USBH->HcControl = (USBH->HcControl & ~OR_CONTROL_HCFS) | OR_CONTROL_HC_RSET; + // HCD must wait 10ms for HC reset complete + wait_ms(100); + + USBH->HcControlHeadED = 0; // Initialize Control ED list head to 0 + USBH->HcBulkHeadED = 0; // Initialize Bulk ED list head to 0 + USBH->HcHCCA = (uint32_t) usb_hcca; + + USBH->HcFmInterval = DEFAULT_FMINTERVAL; // Frame interval = 12000 - 1 + // MPS = 10,104 + USBH->HcPeriodicStart = FI * 90 / 100; // 90% of frame interval + USBH->HcLSThreshold = 0x628; // Low speed threshold + + // Put HC in operational state + USBH->HcControl = (USBH->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; + + // FIXME + USBH->HcRhDescriptorA = USBH->HcRhDescriptorA & ~(USBH_HcRhDescriptorA_NOCP_Msk | USBH_HcRhDescriptorA_OCPM_Msk | USBH_HcRhDescriptorA_PSM_Msk); + // Issue SetGlobalPower command + USBH->HcRhStatus = USBH_HcRhStatus_LPSC_Msk; + // Power On To Power Good Time, in 2 ms units + wait_ms(((USBH->HcRhDescriptorA & USBH_HcRhDescriptorA_POTPGT_Msk) >> USBH_HcRhDescriptorA_POTPGT_Pos) * 2); + + // Clear Interrrupt Status + USBH->HcInterruptStatus |= USBH->HcInterruptStatus; + // Enable interrupts we care about + USBH->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC; + + NVIC_SetVector(USBH_IRQn, (uint32_t)(_usbisr)); + NVIC_EnableIRQ(USBH_IRQn); + + + // Check for any connected devices + if (USBH->HcRhPortStatus[0] & OR_RH_PORT_CCS) { + // Device connected + wait_ms(150); + deviceConnected(0, 1, USBH->HcRhPortStatus[0] & OR_RH_PORT_LSDA); + } + + // Check for any connected devices + if (USBH->HcRhPortStatus[1] & OR_RH_PORT_CCS) { + // Device connected + wait_ms(150); + deviceConnected(0, 2, USBH->HcRhPortStatus[1] & OR_RH_PORT_LSDA); + } +} + +uint32_t USBHALHost::controlHeadED() +{ + return USBH->HcControlHeadED; +} + +uint32_t USBHALHost::bulkHeadED() +{ + return USBH->HcBulkHeadED; +} + +uint32_t USBHALHost::interruptHeadED() +{ + // FIXME: Only support one INT ED? + return usb_hcca->IntTable[0]; +} + +void USBHALHost::updateBulkHeadED(uint32_t addr) +{ + USBH->HcBulkHeadED = addr; +} + + +void USBHALHost::updateControlHeadED(uint32_t addr) +{ + USBH->HcControlHeadED = addr; +} + +void USBHALHost::updateInterruptHeadED(uint32_t addr) +{ + // FIXME: Only support one INT ED? + usb_hcca->IntTable[0] = addr; +} + + +void USBHALHost::enableList(ENDPOINT_TYPE type) +{ + switch(type) { + case CONTROL_ENDPOINT: + USBH->HcCommandStatus = OR_CMD_STATUS_CLF; + USBH->HcControl |= OR_CONTROL_CLE; + break; + case ISOCHRONOUS_ENDPOINT: + // FIXME + break; + case BULK_ENDPOINT: + USBH->HcCommandStatus = OR_CMD_STATUS_BLF; + USBH->HcControl |= OR_CONTROL_BLE; + break; + case INTERRUPT_ENDPOINT: + USBH->HcControl |= OR_CONTROL_PLE; + break; + } +} + + +bool USBHALHost::disableList(ENDPOINT_TYPE type) +{ + switch(type) { + case CONTROL_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_CLE) { + USBH->HcControl &= ~OR_CONTROL_CLE; + return true; + } + return false; + case ISOCHRONOUS_ENDPOINT: + // FIXME + return false; + case BULK_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_BLE) { + USBH->HcControl &= ~OR_CONTROL_BLE; + return true; + } + return false; + case INTERRUPT_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_PLE) { + USBH->HcControl &= ~OR_CONTROL_PLE; + return true; + } + return false; + } + return false; +} + + +void USBHALHost::memInit() +{ + usb_hcca = (volatile HCCA *)usb_buf; + usb_edBuf = usb_buf + HCCA_SIZE; + usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE); +} + +volatile uint8_t * USBHALHost::getED() +{ + for (int i = 0; i < MAX_ENDPOINT; i++) { + if ( !edBufAlloc[i] ) { + edBufAlloc[i] = true; + return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE); + } + } + perror("Could not allocate ED\r\n"); + return NULL; //Could not alloc ED +} + +volatile uint8_t * USBHALHost::getTD() +{ + int i; + for (i = 0; i < MAX_TD; i++) { + if ( !tdBufAlloc[i] ) { + tdBufAlloc[i] = true; + return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE); + } + } + perror("Could not allocate TD\r\n"); + return NULL; //Could not alloc TD +} + + +void USBHALHost::freeED(volatile uint8_t * ed) +{ + int i; + i = (ed - usb_edBuf) / ED_SIZE; + edBufAlloc[i] = false; +} + +void USBHALHost::freeTD(volatile uint8_t * td) +{ + int i; + i = (td - usb_tdBuf) / TD_SIZE; + tdBufAlloc[i] = false; +} + + +void USBHALHost::resetRootHub() +{ + // Reset port1 + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRS; + while (USBH->HcRhPortStatus[0] & OR_RH_PORT_PRS); + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC; + + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRS; + while (USBH->HcRhPortStatus[1] & OR_RH_PORT_PRS); + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRSC; +} + + +void USBHALHost::_usbisr(void) +{ + if (instHost) { + instHost->UsbIrqhandler(); + } +} + +void USBHALHost::UsbIrqhandler() +{ + uint32_t ints = USBH->HcInterruptStatus; + + // Root hub status change interrupt + if (ints & OR_INTR_STATUS_RHSC) { + uint32_t ints_roothub = USBH->HcRhStatus; + uint32_t ints_port1 = USBH->HcRhPortStatus[0]; + uint32_t ints_port2 = USBH->HcRhPortStatus[1]; + + // Port1: ConnectStatusChange + if (ints_port1 & OR_RH_PORT_CSC) { + if (ints_roothub & OR_RH_STATUS_DRWE) { + // When DRWE is on, Connect Status Change means a remote wakeup event. + } else { + if (ints_port1 & OR_RH_PORT_CCS) { + // Root device connected + + // wait 150ms to avoid bounce + wait_ms(150); + + //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed + deviceConnected(0, 1, ints_port1 & OR_RH_PORT_LSDA); + } else { + // Root device disconnected + + if (!(ints & OR_INTR_STATUS_WDH)) { + usb_hcca->DoneHead = 0; + } + + // wait 200ms to avoid bounce + wait_ms(200); + + deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); + + if (ints & OR_INTR_STATUS_WDH) { + usb_hcca->DoneHead = 0; + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + } + } + USBH->HcRhPortStatus[0] = OR_RH_PORT_CSC; + } + + // Port1: ConnectStatusChange + if (ints_port2 & OR_RH_PORT_CSC) { + if (ints_roothub & OR_RH_STATUS_DRWE) { + // When DRWE is on, Connect Status Change means a remote wakeup event. + } else { + if (ints_port2 & OR_RH_PORT_CCS) { + // Root device connected + + // wait 150ms to avoid bounce + wait_ms(150); + + //Hub 0 (root hub), Port 2 (count starts at 2), Low or High speed + deviceConnected(0, 2, ints_port2 & OR_RH_PORT_LSDA); + } else { + // Root device disconnected + + if (!(ints & OR_INTR_STATUS_WDH)) { + usb_hcca->DoneHead = 0; + } + + // wait 200ms to avoid bounce + wait_ms(200); + + deviceDisconnected(0, 2, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); + + if (ints & OR_INTR_STATUS_WDH) { + usb_hcca->DoneHead = 0; + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + } + } + USBH->HcRhPortStatus[1] = OR_RH_PORT_CSC; + } + + + // Port1: Reset completed + if (ints_port1 & OR_RH_PORT_PRSC) { + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC; + } + // Port1: PortEnableStatusChange + if (ints_port1 & OR_RH_PORT_PESC) { + USBH->HcRhPortStatus[0] = OR_RH_PORT_PESC; + } + + // Port2: PortOverCurrentIndicatorChange + if (ints_port2 & OR_RH_PORT_OCIC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_OCIC; + } + + // Port2: Reset completed + if (ints_port2 & OR_RH_PORT_PRSC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRSC; + } + // Port2: PortEnableStatusChange + if (ints_port2 & OR_RH_PORT_PESC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_PESC; + } + USBH->HcInterruptStatus = OR_INTR_STATUS_RHSC; + } + + // Writeback Done Head interrupt + if (ints & OR_INTR_STATUS_WDH) { + transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE); + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + + +} +#endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c index c31aa258e3..44cfe327fd 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c @@ -294,7 +294,7 @@ void HSUSBD_StandardRequest(void) if ((gUsbCmd.bmRequestType & 0x80ul) == 0x80ul) { /* request data transfer direction */ /* Device to host */ switch (gUsbCmd.bRequest) { - case GET_CONFIGURATION: { + case USBD_GET_CONFIGURATION: { /* Return current configuration setting */ HSUSBD_PrepareCtrlIn((uint8_t *)&g_hsusbd_UsbConfig, 1ul); @@ -302,14 +302,14 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); break; } - case GET_DESCRIPTOR: { + case USBD_GET_DESCRIPTOR: { if (!HSUSBD_GetDescriptor()) { HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); } break; } - case GET_INTERFACE: { + case USBD_GET_INTERFACE: { /* Return current interface setting */ HSUSBD_PrepareCtrlIn((uint8_t *)&g_hsusbd_UsbAltInterface, 1ul); @@ -317,7 +317,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); break; } - case GET_STATUS: { + case USBD_GET_STATUS: { /* Device */ if (gUsbCmd.bmRequestType == 0x80ul) { if ((g_hsusbd_sInfo->gu8ConfigDesc[7] & 0x40ul) == 0x40ul) { @@ -350,7 +350,7 @@ void HSUSBD_StandardRequest(void) } else { /* Host to device */ switch (gUsbCmd.bRequest) { - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if((gUsbCmd.wValue & 0xfful) == FEATURE_ENDPOINT_HALT) { uint32_t epNum, i; @@ -370,7 +370,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { g_hsusbd_UsbAddr = (uint8_t)gUsbCmd.wValue; /* Status Stage */ HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); @@ -378,7 +378,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { g_hsusbd_UsbConfig = (uint8_t)gUsbCmd.wValue; g_hsusbd_Configured = (uint8_t)1ul; /* Status stage */ @@ -387,7 +387,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if ((gUsbCmd.wValue & 0x3ul) == 2ul) { /* TEST_MODE */ g_hsusbd_EnableTestMode = (uint8_t)1ul; g_hsusbd_TestSelector = (uint8_t)(gUsbCmd.wIndex >> 8); @@ -402,7 +402,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_INTERFACE: { + case USBD_SET_INTERFACE: { g_hsusbd_UsbAltInterface = (uint8_t)gUsbCmd.wValue; if (g_hsusbd_pfnSetInterface != NULL) { g_hsusbd_pfnSetInterface((uint32_t)g_hsusbd_UsbAltInterface); @@ -442,11 +442,11 @@ void HSUSBD_StandardRequest(void) void HSUSBD_UpdateDeviceState(void) { switch (gUsbCmd.bRequest) { - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { HSUSBD_SET_ADDR(g_hsusbd_UsbAddr); break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { if (g_hsusbd_UsbConfig == 0ul) { uint32_t volatile i; /* Reset PID DATA0 */ @@ -458,7 +458,7 @@ void HSUSBD_UpdateDeviceState(void) } break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if(gUsbCmd.wValue == FEATURE_ENDPOINT_HALT) { uint32_t idx; idx = (uint32_t)(gUsbCmd.wIndex & 0xFul); @@ -479,7 +479,7 @@ void HSUSBD_UpdateDeviceState(void) } break; } - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if(gUsbCmd.wValue == FEATURE_ENDPOINT_HALT) { uint32_t idx; idx = (uint32_t)(gUsbCmd.wIndex & 0xFul); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h index b37faf22a2..c24614bb60 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h @@ -117,7 +117,10 @@ extern "C" #define SYS_USBPHY_USBROLE_STD_USBH (0x1UL << SYS_USBPHY_USBROLE_Pos) /*!< Standard USB host \hideinitializer */ #define SYS_USBPHY_USBROLE_ID_DEPH (0x2UL << SYS_USBPHY_USBROLE_Pos) /*!< ID dependent device \hideinitializer */ #define SYS_USBPHY_USBROLE_ON_THE_GO (0x3UL << SYS_USBPHY_USBROLE_Pos) /*!< On-The-Go device \hideinitializer */ - +#define SYS_USBPHY_HSUSBROLE_STD_USBD (0x0UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< Standard USB device \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_STD_USBH (0x1UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< Standard USB host \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_ID_DEPH (0x2UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< ID dependent device \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_ON_THE_GO (0x3UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< On-The-Go device \hideinitializer */ /*---------------------------------------------------------------------------------------------------------*/ /* Multi-Function constant definitions. */ diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c index b2ae74e40f..cf0919ae43 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c @@ -267,7 +267,7 @@ void USBD_StandardRequest(void) if((g_usbd_SetupPacket[0] & 0x80ul) == 0x80ul) { /* request data transfer direction */ /* Device to host */ switch(g_usbd_SetupPacket[1]) { - case GET_CONFIGURATION: { + case USBD_GET_CONFIGURATION: { /* Return current configuration setting */ /* Data stage */ addr = USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0); @@ -278,12 +278,12 @@ void USBD_StandardRequest(void) USBD_PrepareCtrlOut(0, 0ul); break; } - case GET_DESCRIPTOR: { + case USBD_GET_DESCRIPTOR: { USBD_GetDescriptor(); USBD_PrepareCtrlOut(0, 0ul); /* For status stage */ break; } - case GET_INTERFACE: { + case USBD_GET_INTERFACE: { /* Return current interface setting */ /* Data stage */ addr = USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0); @@ -294,7 +294,7 @@ void USBD_StandardRequest(void) USBD_PrepareCtrlOut(0, 0ul); break; } - case GET_STATUS: { + case USBD_GET_STATUS: { /* Device */ if(g_usbd_SetupPacket[0] == 0x80ul) { uint8_t u8Tmp; @@ -342,7 +342,7 @@ void USBD_StandardRequest(void) } else { /* Host to device */ switch(g_usbd_SetupPacket[1]) { - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) { uint32_t epNum, i; @@ -363,7 +363,7 @@ void USBD_StandardRequest(void) USBD_SET_PAYLOAD_LEN(EP0, 0ul); break; } - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { g_usbd_UsbAddr = g_usbd_SetupPacket[2]; /* Status Stage */ USBD_SET_DATA1(EP0); @@ -371,7 +371,7 @@ void USBD_StandardRequest(void) break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { g_usbd_UsbConfig = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetConfigCallback) { @@ -383,7 +383,7 @@ void USBD_StandardRequest(void) USBD_SET_PAYLOAD_LEN(EP0, 0ul); break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if( (g_usbd_SetupPacket[0] & 0xFul) == 0ul ) { /* 0: device */ if((g_usbd_SetupPacket[2] == 3ul) && (g_usbd_SetupPacket[3] == 0ul)) { /* 3: HNP enable */ OTG->CTL |= (OTG_CTL_HNPREQEN_Msk | OTG_CTL_BUSREQ_Msk); @@ -401,7 +401,7 @@ void USBD_StandardRequest(void) break; } - case SET_INTERFACE: { + case USBD_SET_INTERFACE: { g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetInterface != NULL) { g_usbd_pfnSetInterface(g_usbd_UsbAltInterface); @@ -491,7 +491,7 @@ void USBD_CtrlIn(void) } } else { /* In ACK for Set address */ - if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS)) { + if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) { addr = USBD_GET_ADDR(); if((addr != g_usbd_UsbAddr) && (addr == 0ul)) { USBD_SET_ADDR(g_usbd_UsbAddr); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h index 53ec800535..05813f72a2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h @@ -69,17 +69,17 @@ extern const S_USBD_INFO_T gsInfo; #define REQ_VENDOR 0x40ul /* USB Standard Request */ -#define GET_STATUS 0x00ul -#define CLEAR_FEATURE 0x01ul -#define SET_FEATURE 0x03ul -#define SET_ADDRESS 0x05ul -#define GET_DESCRIPTOR 0x06ul -#define SET_DESCRIPTOR 0x07ul -#define GET_CONFIGURATION 0x08ul -#define SET_CONFIGURATION 0x09ul -#define GET_INTERFACE 0x0Aul -#define SET_INTERFACE 0x0Bul -#define SYNC_FRAME 0x0Cul +#define USBD_GET_STATUS 0x00ul +#define USBD_CLEAR_FEATURE 0x01ul +#define USBD_SET_FEATURE 0x03ul +#define USBD_SET_ADDRESS 0x05ul +#define USBD_GET_DESCRIPTOR 0x06ul +#define USBD_SET_DESCRIPTOR 0x07ul +#define USBD_GET_CONFIGURATION 0x08ul +#define USBD_SET_CONFIGURATION 0x09ul +#define USBD_GET_INTERFACE 0x0Aul +#define USBD_SET_INTERFACE 0x0Bul +#define USBD_SYNC_FRAME 0x0Cul /* USB Descriptor Type */ #define DESC_DEVICE 0x01ul