A copy of the mbed USBDevice with USBSerial library

Dependents:   STM32L0_LoRa Smartage STM32L0_LoRa Turtle_RadioShuttle

Committer:
Helmut Tschemernjak
Date:
Sun Feb 24 14:52:33 2019 +0100
Revision:
8:961423d1da74
Parent:
0:a3ea811f80f2
Added sleep manager support to avoids sleeps while a USB CDC
connection is active

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut64 0:a3ea811f80f2 1 /* mbed Microcontroller Library
Helmut64 0:a3ea811f80f2 2 * Copyright (c) 2015-2016 Nuvoton
Helmut64 0:a3ea811f80f2 3 *
Helmut64 0:a3ea811f80f2 4 * Licensed under the Apache License, Version 2.0 (the "License");
Helmut64 0:a3ea811f80f2 5 * you may not use this file except in compliance with the License.
Helmut64 0:a3ea811f80f2 6 * You may obtain a copy of the License at
Helmut64 0:a3ea811f80f2 7 *
Helmut64 0:a3ea811f80f2 8 * http://www.apache.org/licenses/LICENSE-2.0
Helmut64 0:a3ea811f80f2 9 *
Helmut64 0:a3ea811f80f2 10 * Unless required by applicable law or agreed to in writing, software
Helmut64 0:a3ea811f80f2 11 * distributed under the License is distributed on an "AS IS" BASIS,
Helmut64 0:a3ea811f80f2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Helmut64 0:a3ea811f80f2 13 * See the License for the specific language governing permissions and
Helmut64 0:a3ea811f80f2 14 * limitations under the License.
Helmut64 0:a3ea811f80f2 15 */
Helmut64 0:a3ea811f80f2 16
Helmut64 0:a3ea811f80f2 17 #if defined(TARGET_M480)
Helmut64 0:a3ea811f80f2 18
Helmut64 0:a3ea811f80f2 19 #include "USBHAL.h"
Helmut64 0:a3ea811f80f2 20 #include "M480.h"
Helmut64 0:a3ea811f80f2 21 #include "pinmap.h"
Helmut64 0:a3ea811f80f2 22
Helmut64 0:a3ea811f80f2 23 /**
Helmut64 0:a3ea811f80f2 24 * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN.
Helmut64 0:a3ea811f80f2 25 * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC.
Helmut64 0:a3ea811f80f2 26 */
Helmut64 0:a3ea811f80f2 27
Helmut64 0:a3ea811f80f2 28 USBHAL * USBHAL::instance;
Helmut64 0:a3ea811f80f2 29
Helmut64 0:a3ea811f80f2 30 #if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0)
Helmut64 0:a3ea811f80f2 31
Helmut64 0:a3ea811f80f2 32 /* Global variables for Control Pipe */
Helmut64 0:a3ea811f80f2 33 extern uint8_t g_usbd_SetupPacket[]; /*!< Setup packet buffer */
Helmut64 0:a3ea811f80f2 34
Helmut64 0:a3ea811f80f2 35 static volatile uint32_t s_ep_compl = 0;
Helmut64 0:a3ea811f80f2 36 static volatile uint32_t s_ep_buf_ind = 8;
Helmut64 0:a3ea811f80f2 37 static volatile uint8_t s_usb_addr = 0;
Helmut64 0:a3ea811f80f2 38 static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1};
Helmut64 0:a3ea811f80f2 39 static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0};
Helmut64 0:a3ea811f80f2 40
Helmut64 0:a3ea811f80f2 41 extern volatile uint8_t *g_usbd_CtrlInPointer;
Helmut64 0:a3ea811f80f2 42 extern volatile uint32_t g_usbd_CtrlInSize;
Helmut64 0:a3ea811f80f2 43 extern volatile uint8_t *g_usbd_CtrlOutPointer;
Helmut64 0:a3ea811f80f2 44 extern volatile uint32_t g_usbd_CtrlOutSize;
Helmut64 0:a3ea811f80f2 45 extern volatile uint32_t g_usbd_CtrlOutSizeLimit;
Helmut64 0:a3ea811f80f2 46 extern volatile uint32_t g_usbd_UsbConfig;
Helmut64 0:a3ea811f80f2 47 extern volatile uint32_t g_usbd_CtrlMaxPktSize;
Helmut64 0:a3ea811f80f2 48 extern volatile uint32_t g_usbd_UsbAltInterface;
Helmut64 0:a3ea811f80f2 49 volatile uint32_t g_usbd_CepTransferLen = 0;
Helmut64 0:a3ea811f80f2 50 volatile uint32_t frame_cnt = 0;
Helmut64 0:a3ea811f80f2 51
Helmut64 0:a3ea811f80f2 52 USBHAL::USBHAL(void)
Helmut64 0:a3ea811f80f2 53 {
Helmut64 0:a3ea811f80f2 54 SYS_UnlockReg();
Helmut64 0:a3ea811f80f2 55
Helmut64 0:a3ea811f80f2 56 s_ep_buf_ind = 8;
Helmut64 0:a3ea811f80f2 57
Helmut64 0:a3ea811f80f2 58 memset(epCallback, 0x00, sizeof (epCallback));
Helmut64 0:a3ea811f80f2 59 epCallback[0] = &USBHAL::EP1_OUT_callback;
Helmut64 0:a3ea811f80f2 60 epCallback[1] = &USBHAL::EP2_IN_callback;
Helmut64 0:a3ea811f80f2 61 epCallback[2] = &USBHAL::EP3_OUT_callback;
Helmut64 0:a3ea811f80f2 62 epCallback[3] = &USBHAL::EP4_IN_callback;
Helmut64 0:a3ea811f80f2 63 epCallback[4] = &USBHAL::EP5_OUT_callback;
Helmut64 0:a3ea811f80f2 64 epCallback[5] = &USBHAL::EP6_IN_callback;
Helmut64 0:a3ea811f80f2 65 epCallback[6] = &USBHAL::EP7_OUT_callback;
Helmut64 0:a3ea811f80f2 66 epCallback[7] = &USBHAL::EP8_IN_callback;
Helmut64 0:a3ea811f80f2 67 epCallback[8] = &USBHAL::EP9_OUT_callback;
Helmut64 0:a3ea811f80f2 68 epCallback[9] = &USBHAL::EP10_IN_callback;
Helmut64 0:a3ea811f80f2 69 epCallback[10] = &USBHAL::EP11_OUT_callback;
Helmut64 0:a3ea811f80f2 70 epCallback[11] = &USBHAL::EP12_IN_callback;
Helmut64 0:a3ea811f80f2 71
Helmut64 0:a3ea811f80f2 72 instance = this;
Helmut64 0:a3ea811f80f2 73
Helmut64 0:a3ea811f80f2 74 /* Configure USB to Device mode */
Helmut64 0:a3ea811f80f2 75 SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_USBROLE_STD_USBD;
Helmut64 0:a3ea811f80f2 76
Helmut64 0:a3ea811f80f2 77 /* Enable USB PHY */
Helmut64 0:a3ea811f80f2 78 SYS->USBPHY |= SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk;
Helmut64 0:a3ea811f80f2 79
Helmut64 0:a3ea811f80f2 80 /* Select IP clock source */
Helmut64 0:a3ea811f80f2 81 CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | CLK_CLKDIV0_USB(4);
Helmut64 0:a3ea811f80f2 82
Helmut64 0:a3ea811f80f2 83 /* Enable IP clock */
Helmut64 0:a3ea811f80f2 84 CLK_EnableModuleClock(USBD_MODULE);
Helmut64 0:a3ea811f80f2 85
Helmut64 0:a3ea811f80f2 86 /* Configure pins for USB 1.1 port: VBUS/D+/D-/ID */
Helmut64 0:a3ea811f80f2 87 pin_function(PA_12, SYS_GPA_MFPH_PA12MFP_USB_VBUS);
Helmut64 0:a3ea811f80f2 88 pin_function(PA_13, SYS_GPA_MFPH_PA13MFP_USB_D_N);
Helmut64 0:a3ea811f80f2 89 pin_function(PA_14, SYS_GPA_MFPH_PA14MFP_USB_D_P);
Helmut64 0:a3ea811f80f2 90 pin_function(PA_15, (int) SYS_GPA_MFPH_PA15MFP_USB_OTG_ID);
Helmut64 0:a3ea811f80f2 91
Helmut64 0:a3ea811f80f2 92 /* Initial USB engine */
Helmut64 0:a3ea811f80f2 93 USBD->ATTR = 0x7D0;
Helmut64 0:a3ea811f80f2 94
Helmut64 0:a3ea811f80f2 95 /* Set SE0 (disconnect) */
Helmut64 0:a3ea811f80f2 96 USBD_SET_SE0();
Helmut64 0:a3ea811f80f2 97
Helmut64 0:a3ea811f80f2 98 //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr);
Helmut64 0:a3ea811f80f2 99 NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr);
Helmut64 0:a3ea811f80f2 100 NVIC_EnableIRQ(USBD_IRQn);
Helmut64 0:a3ea811f80f2 101 }
Helmut64 0:a3ea811f80f2 102
Helmut64 0:a3ea811f80f2 103 USBHAL::~USBHAL(void)
Helmut64 0:a3ea811f80f2 104 {
Helmut64 0:a3ea811f80f2 105 NVIC_DisableIRQ(USBD_IRQn);
Helmut64 0:a3ea811f80f2 106 USBD_SET_SE0();
Helmut64 0:a3ea811f80f2 107 USBD_DISABLE_PHY();
Helmut64 0:a3ea811f80f2 108 }
Helmut64 0:a3ea811f80f2 109
Helmut64 0:a3ea811f80f2 110 void USBHAL::connect(void)
Helmut64 0:a3ea811f80f2 111 {
Helmut64 0:a3ea811f80f2 112 USBD->STBUFSEG = 0;
Helmut64 0:a3ea811f80f2 113 frame_cnt = 0;
Helmut64 0:a3ea811f80f2 114 /* EP0 ==> control IN endpoint, address 0 */
Helmut64 0:a3ea811f80f2 115 USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
Helmut64 0:a3ea811f80f2 116 /* Buffer range for EP0 */
Helmut64 0:a3ea811f80f2 117 USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind);
Helmut64 0:a3ea811f80f2 118
Helmut64 0:a3ea811f80f2 119 /* EP1 ==> control OUT endpoint, address 0 */
Helmut64 0:a3ea811f80f2 120 USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
Helmut64 0:a3ea811f80f2 121 /* Buffer range for EP1 */
Helmut64 0:a3ea811f80f2 122 USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind);
Helmut64 0:a3ea811f80f2 123
Helmut64 0:a3ea811f80f2 124 s_ep_buf_ind += MAX_PACKET_SIZE_EP0;
Helmut64 0:a3ea811f80f2 125
Helmut64 0:a3ea811f80f2 126 /* Disable software-disconnect function */
Helmut64 0:a3ea811f80f2 127 USBD_CLR_SE0();
Helmut64 0:a3ea811f80f2 128
Helmut64 0:a3ea811f80f2 129 /* Clear USB-related interrupts before enable interrupt */
Helmut64 0:a3ea811f80f2 130 USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
Helmut64 0:a3ea811f80f2 131
Helmut64 0:a3ea811f80f2 132 /* Enable USB-related interrupts. */
Helmut64 0:a3ea811f80f2 133 USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
Helmut64 0:a3ea811f80f2 134 }
Helmut64 0:a3ea811f80f2 135
Helmut64 0:a3ea811f80f2 136 void USBHAL::disconnect(void)
Helmut64 0:a3ea811f80f2 137 {
Helmut64 0:a3ea811f80f2 138 /* Set SE0 (disconnect) */
Helmut64 0:a3ea811f80f2 139 USBD_SET_SE0();
Helmut64 0:a3ea811f80f2 140 }
Helmut64 0:a3ea811f80f2 141
Helmut64 0:a3ea811f80f2 142 void USBHAL::configureDevice(void)
Helmut64 0:a3ea811f80f2 143 {
Helmut64 0:a3ea811f80f2 144 /**
Helmut64 0:a3ea811f80f2 145 * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()).
Helmut64 0:a3ea811f80f2 146 * So we have the following USB buffer management policy:
Helmut64 0:a3ea811f80f2 147 * 1. Allocate for CEP on connect().
Helmut64 0:a3ea811f80f2 148 * 2. Allocate for EPX in realiseEndpoint().
Helmut64 0:a3ea811f80f2 149 * 3. Deallocate all except for CEP in unconfigureDevice().
Helmut64 0:a3ea811f80f2 150 */
Helmut64 0:a3ea811f80f2 151 }
Helmut64 0:a3ea811f80f2 152
Helmut64 0:a3ea811f80f2 153 void USBHAL::unconfigureDevice(void)
Helmut64 0:a3ea811f80f2 154 {
Helmut64 0:a3ea811f80f2 155 s_ep_buf_ind = 8;
Helmut64 0:a3ea811f80f2 156 }
Helmut64 0:a3ea811f80f2 157
Helmut64 0:a3ea811f80f2 158 void USBHAL::setAddress(uint8_t address)
Helmut64 0:a3ea811f80f2 159 {
Helmut64 0:a3ea811f80f2 160 // NOTE: Delay address setting; otherwise, USB controller won't ack.
Helmut64 0:a3ea811f80f2 161 s_usb_addr = address;
Helmut64 0:a3ea811f80f2 162 }
Helmut64 0:a3ea811f80f2 163
Helmut64 0:a3ea811f80f2 164 void USBHAL::remoteWakeup(void)
Helmut64 0:a3ea811f80f2 165 {
Helmut64 0:a3ea811f80f2 166 #if 0
Helmut64 0:a3ea811f80f2 167 USBD->OPER |= USBD_OPER_RESUMEEN_Msk;
Helmut64 0:a3ea811f80f2 168 #endif
Helmut64 0:a3ea811f80f2 169 }
Helmut64 0:a3ea811f80f2 170
Helmut64 0:a3ea811f80f2 171 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
Helmut64 0:a3ea811f80f2 172 {
Helmut64 0:a3ea811f80f2 173 uint32_t ep_type = 0;
Helmut64 0:a3ea811f80f2 174 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 175 uint32_t ep_logic_index = NU_EP2EPL(endpoint);
Helmut64 0:a3ea811f80f2 176 uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT;
Helmut64 0:a3ea811f80f2 177
Helmut64 0:a3ea811f80f2 178 if(ep_logic_index == 3 || ep_logic_index == 4)
Helmut64 0:a3ea811f80f2 179 ep_type = USBD_CFG_TYPE_ISO;
Helmut64 0:a3ea811f80f2 180
Helmut64 0:a3ea811f80f2 181 USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index);
Helmut64 0:a3ea811f80f2 182 /* Buffer range */
Helmut64 0:a3ea811f80f2 183 USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind);
Helmut64 0:a3ea811f80f2 184
Helmut64 0:a3ea811f80f2 185 if(ep_dir == USBD_CFG_EPMODE_OUT)
Helmut64 0:a3ea811f80f2 186 USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket);
Helmut64 0:a3ea811f80f2 187
Helmut64 0:a3ea811f80f2 188 s_ep_mxp[ep_logic_index] = maxPacket;
Helmut64 0:a3ea811f80f2 189
Helmut64 0:a3ea811f80f2 190 s_ep_buf_ind += maxPacket;
Helmut64 0:a3ea811f80f2 191
Helmut64 0:a3ea811f80f2 192 return true;
Helmut64 0:a3ea811f80f2 193 }
Helmut64 0:a3ea811f80f2 194
Helmut64 0:a3ea811f80f2 195 void USBHAL::EP0setup(uint8_t *buffer)
Helmut64 0:a3ea811f80f2 196 {
Helmut64 0:a3ea811f80f2 197 uint32_t sz;
Helmut64 0:a3ea811f80f2 198 endpointReadResult(EP0OUT, buffer, &sz);
Helmut64 0:a3ea811f80f2 199 }
Helmut64 0:a3ea811f80f2 200
Helmut64 0:a3ea811f80f2 201 void USBHAL::EP0read(void)
Helmut64 0:a3ea811f80f2 202 {
Helmut64 0:a3ea811f80f2 203
Helmut64 0:a3ea811f80f2 204
Helmut64 0:a3ea811f80f2 205 }
Helmut64 0:a3ea811f80f2 206
Helmut64 0:a3ea811f80f2 207 void USBHAL::EP0readStage(void)
Helmut64 0:a3ea811f80f2 208 {
Helmut64 0:a3ea811f80f2 209 // N/A
Helmut64 0:a3ea811f80f2 210
Helmut64 0:a3ea811f80f2 211 USBD_PrepareCtrlOut(0,0);
Helmut64 0:a3ea811f80f2 212 }
Helmut64 0:a3ea811f80f2 213
Helmut64 0:a3ea811f80f2 214 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
Helmut64 0:a3ea811f80f2 215 {
Helmut64 0:a3ea811f80f2 216 uint32_t i;
Helmut64 0:a3ea811f80f2 217 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1));
Helmut64 0:a3ea811f80f2 218 uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1);
Helmut64 0:a3ea811f80f2 219 for (i = 0; i < ceprxcnt; i ++)
Helmut64 0:a3ea811f80f2 220 buffer[i] = buf[i];
Helmut64 0:a3ea811f80f2 221 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
Helmut64 0:a3ea811f80f2 222 return ceprxcnt;
Helmut64 0:a3ea811f80f2 223 }
Helmut64 0:a3ea811f80f2 224
Helmut64 0:a3ea811f80f2 225 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
Helmut64 0:a3ea811f80f2 226 {
Helmut64 0:a3ea811f80f2 227 if (buffer && size) {
Helmut64 0:a3ea811f80f2 228 if(s_ep_data_bit[0] & 1)
Helmut64 0:a3ea811f80f2 229 USBD_SET_DATA1(EP0);
Helmut64 0:a3ea811f80f2 230 else
Helmut64 0:a3ea811f80f2 231 USBD_SET_DATA0(EP0);
Helmut64 0:a3ea811f80f2 232 s_ep_data_bit[0]++;
Helmut64 0:a3ea811f80f2 233
Helmut64 0:a3ea811f80f2 234 USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size);
Helmut64 0:a3ea811f80f2 235 USBD_SET_PAYLOAD_LEN(EP0, size);
Helmut64 0:a3ea811f80f2 236 if(size < MAX_PACKET_SIZE_EP0)
Helmut64 0:a3ea811f80f2 237 s_ep_data_bit[0] = 1;
Helmut64 0:a3ea811f80f2 238
Helmut64 0:a3ea811f80f2 239 } else {
Helmut64 0:a3ea811f80f2 240 if(g_usbd_SetupPacket[0] & 0x80) { //Device to Host
Helmut64 0:a3ea811f80f2 241 // Status stage
Helmut64 0:a3ea811f80f2 242 // USBD_PrepareCtrlOut(0,0);
Helmut64 0:a3ea811f80f2 243 } else {
Helmut64 0:a3ea811f80f2 244 USBD_SET_DATA1(EP0);
Helmut64 0:a3ea811f80f2 245 USBD_SET_PAYLOAD_LEN(EP0, 0);
Helmut64 0:a3ea811f80f2 246 }
Helmut64 0:a3ea811f80f2 247 }
Helmut64 0:a3ea811f80f2 248 }
Helmut64 0:a3ea811f80f2 249
Helmut64 0:a3ea811f80f2 250 void USBHAL::EP0getWriteResult(void)
Helmut64 0:a3ea811f80f2 251 {
Helmut64 0:a3ea811f80f2 252 // N/A
Helmut64 0:a3ea811f80f2 253 }
Helmut64 0:a3ea811f80f2 254
Helmut64 0:a3ea811f80f2 255 void USBHAL::EP0stall(void)
Helmut64 0:a3ea811f80f2 256 {
Helmut64 0:a3ea811f80f2 257 stallEndpoint(EP0OUT);
Helmut64 0:a3ea811f80f2 258 }
Helmut64 0:a3ea811f80f2 259
Helmut64 0:a3ea811f80f2 260 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
Helmut64 0:a3ea811f80f2 261 {
Helmut64 0:a3ea811f80f2 262 return EP_PENDING;
Helmut64 0:a3ea811f80f2 263 }
Helmut64 0:a3ea811f80f2 264
Helmut64 0:a3ea811f80f2 265 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng
Helmut64 0:a3ea811f80f2 266 {
Helmut64 0:a3ea811f80f2 267 if(endpoint == EP0OUT) {
Helmut64 0:a3ea811f80f2 268 USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
Helmut64 0:a3ea811f80f2 269 if (buffer) {
Helmut64 0:a3ea811f80f2 270 USBD_MemCopy(buffer, g_usbd_SetupPacket, 8);
Helmut64 0:a3ea811f80f2 271 }
Helmut64 0:a3ea811f80f2 272 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
Helmut64 0:a3ea811f80f2 273 } else {
Helmut64 0:a3ea811f80f2 274 uint32_t i;
Helmut64 0:a3ea811f80f2 275 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint)));
Helmut64 0:a3ea811f80f2 276 uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint));
Helmut64 0:a3ea811f80f2 277 for (i = 0; i < eprxcnt; i ++)
Helmut64 0:a3ea811f80f2 278 buffer[i] = buf[i];
Helmut64 0:a3ea811f80f2 279
Helmut64 0:a3ea811f80f2 280 *bytesRead = eprxcnt;
Helmut64 0:a3ea811f80f2 281
Helmut64 0:a3ea811f80f2 282 USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]);
Helmut64 0:a3ea811f80f2 283 }
Helmut64 0:a3ea811f80f2 284 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 285 }
Helmut64 0:a3ea811f80f2 286
Helmut64 0:a3ea811f80f2 287
Helmut64 0:a3ea811f80f2 288 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer)
Helmut64 0:a3ea811f80f2 289 {
Helmut64 0:a3ea811f80f2 290 return 0;
Helmut64 0:a3ea811f80f2 291 }
Helmut64 0:a3ea811f80f2 292
Helmut64 0:a3ea811f80f2 293 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
Helmut64 0:a3ea811f80f2 294 {
Helmut64 0:a3ea811f80f2 295 uint32_t ep_logic_index = NU_EP2EPL(endpoint);
Helmut64 0:a3ea811f80f2 296 if(ep_logic_index == 0)
Helmut64 0:a3ea811f80f2 297 return EP_INVALID;
Helmut64 0:a3ea811f80f2 298 else {
Helmut64 0:a3ea811f80f2 299 uint8_t *buf;
Helmut64 0:a3ea811f80f2 300 uint32_t i=0;
Helmut64 0:a3ea811f80f2 301 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 302 s_ep_compl |= (1 << ep_logic_index);
Helmut64 0:a3ea811f80f2 303 buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index));
Helmut64 0:a3ea811f80f2 304 for(i=0; i<size; i++)
Helmut64 0:a3ea811f80f2 305 buf[i] = data[i];
Helmut64 0:a3ea811f80f2 306
Helmut64 0:a3ea811f80f2 307 /* Set transfer length and trigger IN transfer */
Helmut64 0:a3ea811f80f2 308 USBD_SET_PAYLOAD_LEN(ep_hw_index, size);
Helmut64 0:a3ea811f80f2 309
Helmut64 0:a3ea811f80f2 310 }
Helmut64 0:a3ea811f80f2 311 return EP_PENDING;
Helmut64 0:a3ea811f80f2 312 }
Helmut64 0:a3ea811f80f2 313
Helmut64 0:a3ea811f80f2 314 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 315 {
Helmut64 0:a3ea811f80f2 316 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
Helmut64 0:a3ea811f80f2 317 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 318 return EP_PENDING;
Helmut64 0:a3ea811f80f2 319 }
Helmut64 0:a3ea811f80f2 320
Helmut64 0:a3ea811f80f2 321 void USBHAL::stallEndpoint(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 322 {
Helmut64 0:a3ea811f80f2 323 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 324 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 325 return;
Helmut64 0:a3ea811f80f2 326
Helmut64 0:a3ea811f80f2 327 USBD_SetStall(NU_EPH2EPL(ep_hw_index));
Helmut64 0:a3ea811f80f2 328
Helmut64 0:a3ea811f80f2 329 }
Helmut64 0:a3ea811f80f2 330
Helmut64 0:a3ea811f80f2 331 void USBHAL::unstallEndpoint(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 332 {
Helmut64 0:a3ea811f80f2 333 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 334 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 335 return;
Helmut64 0:a3ea811f80f2 336 USBD_ClearStall(NU_EPH2EPL(ep_hw_index));
Helmut64 0:a3ea811f80f2 337 }
Helmut64 0:a3ea811f80f2 338
Helmut64 0:a3ea811f80f2 339 bool USBHAL::getEndpointStallState(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 340 {
Helmut64 0:a3ea811f80f2 341 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 342 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 343 return false;
Helmut64 0:a3ea811f80f2 344
Helmut64 0:a3ea811f80f2 345 return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0;
Helmut64 0:a3ea811f80f2 346 }
Helmut64 0:a3ea811f80f2 347
Helmut64 0:a3ea811f80f2 348 void USBHAL::_usbisr(void)
Helmut64 0:a3ea811f80f2 349 {
Helmut64 0:a3ea811f80f2 350 MBED_ASSERT(instance);
Helmut64 0:a3ea811f80f2 351 instance->usbisr();
Helmut64 0:a3ea811f80f2 352 }
Helmut64 0:a3ea811f80f2 353
Helmut64 0:a3ea811f80f2 354 void USBHAL::usbisr(void)
Helmut64 0:a3ea811f80f2 355 {
Helmut64 0:a3ea811f80f2 356 uint32_t u32IntSts = USBD_GET_INT_FLAG();
Helmut64 0:a3ea811f80f2 357 uint32_t u32State = USBD_GET_BUS_STATE();
Helmut64 0:a3ea811f80f2 358
Helmut64 0:a3ea811f80f2 359 //------------------------------------------------------------------
Helmut64 0:a3ea811f80f2 360 if(u32IntSts & USBD_INTSTS_VBDETIF_Msk) {
Helmut64 0:a3ea811f80f2 361 // Floating detect
Helmut64 0:a3ea811f80f2 362 USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
Helmut64 0:a3ea811f80f2 363
Helmut64 0:a3ea811f80f2 364 if(USBD_IS_ATTACHED()) {
Helmut64 0:a3ea811f80f2 365 /* USB Plug In */
Helmut64 0:a3ea811f80f2 366 USBD_ENABLE_USB();
Helmut64 0:a3ea811f80f2 367 } else {
Helmut64 0:a3ea811f80f2 368 /* USB Un-plug */
Helmut64 0:a3ea811f80f2 369 USBD_DISABLE_USB();
Helmut64 0:a3ea811f80f2 370 }
Helmut64 0:a3ea811f80f2 371 }
Helmut64 0:a3ea811f80f2 372
Helmut64 0:a3ea811f80f2 373 //------------------------------------------------------------------
Helmut64 0:a3ea811f80f2 374 if(u32IntSts & USBD_INTSTS_BUSIF_Msk) {
Helmut64 0:a3ea811f80f2 375 /* Clear event flag */
Helmut64 0:a3ea811f80f2 376 USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
Helmut64 0:a3ea811f80f2 377
Helmut64 0:a3ea811f80f2 378 if(u32State & USBD_ATTR_USBRST_Msk) {
Helmut64 0:a3ea811f80f2 379 /* Bus reset */
Helmut64 0:a3ea811f80f2 380 USBD_ENABLE_USB();
Helmut64 0:a3ea811f80f2 381 USBD_SwReset();
Helmut64 0:a3ea811f80f2 382 }
Helmut64 0:a3ea811f80f2 383 if(u32State & USBD_ATTR_SUSPEND_Msk) {
Helmut64 0:a3ea811f80f2 384 /* Enable USB but disable PHY */
Helmut64 0:a3ea811f80f2 385 USBD_DISABLE_PHY();
Helmut64 0:a3ea811f80f2 386 }
Helmut64 0:a3ea811f80f2 387 if(u32State & USBD_ATTR_RESUME_Msk) {
Helmut64 0:a3ea811f80f2 388 /* Enable USB and enable PHY */
Helmut64 0:a3ea811f80f2 389 USBD_ENABLE_USB();
Helmut64 0:a3ea811f80f2 390 }
Helmut64 0:a3ea811f80f2 391 }
Helmut64 0:a3ea811f80f2 392
Helmut64 0:a3ea811f80f2 393 if(u32IntSts & USBD_INTSTS_USBIF_Msk) {
Helmut64 0:a3ea811f80f2 394 // USB event
Helmut64 0:a3ea811f80f2 395 if(u32IntSts & USBD_INTSTS_SETUP_Msk) {
Helmut64 0:a3ea811f80f2 396 // Setup packet
Helmut64 0:a3ea811f80f2 397 /* Clear event flag */
Helmut64 0:a3ea811f80f2 398 USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
Helmut64 0:a3ea811f80f2 399
Helmut64 0:a3ea811f80f2 400 /* Clear the data IN/OUT ready flag of control end-points */
Helmut64 0:a3ea811f80f2 401 USBD_STOP_TRANSACTION(EP0);
Helmut64 0:a3ea811f80f2 402 USBD_STOP_TRANSACTION(EP1);
Helmut64 0:a3ea811f80f2 403 EP0setupCallback();
Helmut64 0:a3ea811f80f2 404 }
Helmut64 0:a3ea811f80f2 405
Helmut64 0:a3ea811f80f2 406 // EP events
Helmut64 0:a3ea811f80f2 407 if(u32IntSts & USBD_INTSTS_EP0) {
Helmut64 0:a3ea811f80f2 408 /* Clear event flag */
Helmut64 0:a3ea811f80f2 409 USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
Helmut64 0:a3ea811f80f2 410 // control IN
Helmut64 0:a3ea811f80f2 411 EP0in();
Helmut64 0:a3ea811f80f2 412
Helmut64 0:a3ea811f80f2 413 // In ACK for Set address
Helmut64 0:a3ea811f80f2 414 if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) {
Helmut64 0:a3ea811f80f2 415 if((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0)) {
Helmut64 0:a3ea811f80f2 416 USBD_SET_ADDR(s_usb_addr);
Helmut64 0:a3ea811f80f2 417 }
Helmut64 0:a3ea811f80f2 418 }
Helmut64 0:a3ea811f80f2 419 }
Helmut64 0:a3ea811f80f2 420 if(u32IntSts & USBD_INTSTS_EP1) {
Helmut64 0:a3ea811f80f2 421 /* Clear event flag */
Helmut64 0:a3ea811f80f2 422 USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
Helmut64 0:a3ea811f80f2 423
Helmut64 0:a3ea811f80f2 424 // control OUT
Helmut64 0:a3ea811f80f2 425 EP0out();
Helmut64 0:a3ea811f80f2 426 }
Helmut64 0:a3ea811f80f2 427
Helmut64 0:a3ea811f80f2 428 uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F;
Helmut64 0:a3ea811f80f2 429 uint32_t ep_hw_index = 2;
Helmut64 0:a3ea811f80f2 430 while (gintsts_epx) {
Helmut64 0:a3ea811f80f2 431 if(gintsts_epx & 0x01) {
Helmut64 0:a3ea811f80f2 432 uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7;
Helmut64 0:a3ea811f80f2 433 /* Clear event flag */
Helmut64 0:a3ea811f80f2 434 USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16));
Helmut64 0:a3ea811f80f2 435
Helmut64 0:a3ea811f80f2 436 if(ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3)) { //RX
Helmut64 0:a3ea811f80f2 437 if(ep_status == 0x07)
Helmut64 0:a3ea811f80f2 438 SOF(frame_cnt++);
Helmut64 0:a3ea811f80f2 439 if ((instance->*(epCallback[ep_hw_index-2]))()) {
Helmut64 0:a3ea811f80f2 440
Helmut64 0:a3ea811f80f2 441 }
Helmut64 0:a3ea811f80f2 442 USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]);
Helmut64 0:a3ea811f80f2 443 } else if(ep_status == 0x00 || ep_status == 0x07) { //TX
Helmut64 0:a3ea811f80f2 444 s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index)));
Helmut64 0:a3ea811f80f2 445 if ((instance->*(epCallback[ep_hw_index-2]))()) {
Helmut64 0:a3ea811f80f2 446 }
Helmut64 0:a3ea811f80f2 447 }
Helmut64 0:a3ea811f80f2 448 }
Helmut64 0:a3ea811f80f2 449
Helmut64 0:a3ea811f80f2 450 gintsts_epx = gintsts_epx >> 1;
Helmut64 0:a3ea811f80f2 451 ep_hw_index++;
Helmut64 0:a3ea811f80f2 452 }
Helmut64 0:a3ea811f80f2 453 }
Helmut64 0:a3ea811f80f2 454 }
Helmut64 0:a3ea811f80f2 455 #else
Helmut64 0:a3ea811f80f2 456
Helmut64 0:a3ea811f80f2 457 static volatile uint32_t s_ep_compl = 0;
Helmut64 0:a3ea811f80f2 458 static volatile uint32_t s_ep_buf_ind = 0;
Helmut64 0:a3ea811f80f2 459 static volatile uint8_t s_usb_addr = 0;
Helmut64 0:a3ea811f80f2 460 static volatile S_HSUSBD_CMD_T s_setup;
Helmut64 0:a3ea811f80f2 461 static volatile uint16_t s_ctrlin_packetsize;
Helmut64 0:a3ea811f80f2 462 static uint8_t *g_usbd_CtrlInPointer = 0;
Helmut64 0:a3ea811f80f2 463 static uint32_t g_usbd_CtrlMaxPktSize = 64;
Helmut64 0:a3ea811f80f2 464 static volatile uint32_t g_usbd_CtrlInSize;
Helmut64 0:a3ea811f80f2 465 static uint32_t g_usbd_ShortPacket = 0;
Helmut64 0:a3ea811f80f2 466 //static uint32_t gEpRead = 0;
Helmut64 0:a3ea811f80f2 467 static uint32_t gEpReadCnt = 0;
Helmut64 0:a3ea811f80f2 468
Helmut64 0:a3ea811f80f2 469 void HSUSBD_CtrlInput(void)
Helmut64 0:a3ea811f80f2 470 {
Helmut64 0:a3ea811f80f2 471 unsigned volatile i;
Helmut64 0:a3ea811f80f2 472 uint32_t volatile count;
Helmut64 0:a3ea811f80f2 473
Helmut64 0:a3ea811f80f2 474 // Process remained data
Helmut64 0:a3ea811f80f2 475 if(g_usbd_CtrlInSize >= g_usbd_CtrlMaxPktSize) {
Helmut64 0:a3ea811f80f2 476 // Data size > MXPLD
Helmut64 0:a3ea811f80f2 477 for (i=0; i<(g_usbd_CtrlMaxPktSize >> 2); i++, g_usbd_CtrlInPointer+=4)
Helmut64 0:a3ea811f80f2 478 HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
Helmut64 0:a3ea811f80f2 479 HSUSBD_START_CEP_IN(g_usbd_CtrlMaxPktSize);
Helmut64 0:a3ea811f80f2 480 g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
Helmut64 0:a3ea811f80f2 481 } else {
Helmut64 0:a3ea811f80f2 482 // Data size <= MXPLD
Helmut64 0:a3ea811f80f2 483 for (i=0; i<(g_usbd_CtrlInSize >> 2); i++, g_usbd_CtrlInPointer+=4)
Helmut64 0:a3ea811f80f2 484 HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer;
Helmut64 0:a3ea811f80f2 485
Helmut64 0:a3ea811f80f2 486 count = g_usbd_CtrlInSize % 4;
Helmut64 0:a3ea811f80f2 487 for (i=0; i<count; i++)
Helmut64 0:a3ea811f80f2 488 HSUSBD->CEPDAT_BYTE = *(uint8_t *)(g_usbd_CtrlInPointer + i);
Helmut64 0:a3ea811f80f2 489
Helmut64 0:a3ea811f80f2 490 HSUSBD_START_CEP_IN(g_usbd_CtrlInSize);
Helmut64 0:a3ea811f80f2 491 g_usbd_CtrlInPointer = 0;
Helmut64 0:a3ea811f80f2 492 g_usbd_CtrlInSize = 0;
Helmut64 0:a3ea811f80f2 493 }
Helmut64 0:a3ea811f80f2 494 }
Helmut64 0:a3ea811f80f2 495
Helmut64 0:a3ea811f80f2 496 USBHAL::USBHAL(void)
Helmut64 0:a3ea811f80f2 497 {
Helmut64 0:a3ea811f80f2 498 SYS_UnlockReg();
Helmut64 0:a3ea811f80f2 499
Helmut64 0:a3ea811f80f2 500 s_ep_buf_ind = 0;
Helmut64 0:a3ea811f80f2 501
Helmut64 0:a3ea811f80f2 502 memset(epCallback, 0x00, sizeof (epCallback));
Helmut64 0:a3ea811f80f2 503 epCallback[0] = &USBHAL::EP1_OUT_callback;
Helmut64 0:a3ea811f80f2 504 epCallback[1] = &USBHAL::EP2_IN_callback;
Helmut64 0:a3ea811f80f2 505 epCallback[2] = &USBHAL::EP3_OUT_callback;
Helmut64 0:a3ea811f80f2 506 epCallback[3] = &USBHAL::EP4_IN_callback;
Helmut64 0:a3ea811f80f2 507 epCallback[4] = &USBHAL::EP5_OUT_callback;
Helmut64 0:a3ea811f80f2 508 epCallback[5] = &USBHAL::EP6_IN_callback;
Helmut64 0:a3ea811f80f2 509 epCallback[6] = &USBHAL::EP7_OUT_callback;
Helmut64 0:a3ea811f80f2 510 epCallback[7] = &USBHAL::EP8_IN_callback;
Helmut64 0:a3ea811f80f2 511 epCallback[8] = &USBHAL::EP9_OUT_callback;
Helmut64 0:a3ea811f80f2 512 epCallback[9] = &USBHAL::EP10_IN_callback;
Helmut64 0:a3ea811f80f2 513 epCallback[10] = &USBHAL::EP11_OUT_callback;
Helmut64 0:a3ea811f80f2 514 epCallback[11] = &USBHAL::EP12_IN_callback;
Helmut64 0:a3ea811f80f2 515
Helmut64 0:a3ea811f80f2 516 instance = this;
Helmut64 0:a3ea811f80f2 517
Helmut64 0:a3ea811f80f2 518 /* Configure HSUSB to Device mode */
Helmut64 0:a3ea811f80f2 519 SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_HSUSBROLE_Msk) | SYS_USBPHY_HSUSBROLE_STD_USBD;
Helmut64 0:a3ea811f80f2 520 /* Enable HSUSB PHY */
Helmut64 0:a3ea811f80f2 521 SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_HSUSBACT_Msk)) | SYS_USBPHY_HSUSBEN_Msk;
Helmut64 0:a3ea811f80f2 522 /* Delay >10 us and then switch HSUSB PHY from reset state to active state */
Helmut64 0:a3ea811f80f2 523 wait_us(10);
Helmut64 0:a3ea811f80f2 524 SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk;
Helmut64 0:a3ea811f80f2 525
Helmut64 0:a3ea811f80f2 526 /* Enable USBD module clock */
Helmut64 0:a3ea811f80f2 527 CLK_EnableModuleClock(HSUSBD_MODULE);
Helmut64 0:a3ea811f80f2 528
Helmut64 0:a3ea811f80f2 529 /* Enable USB PHY and wait for it ready */
Helmut64 0:a3ea811f80f2 530 HSUSBD_ENABLE_PHY();
Helmut64 0:a3ea811f80f2 531 while (1) {
Helmut64 0:a3ea811f80f2 532 HSUSBD->EP[0].EPMPS = 0x20;
Helmut64 0:a3ea811f80f2 533 if (HSUSBD->EP[0].EPMPS == 0x20)
Helmut64 0:a3ea811f80f2 534 break;
Helmut64 0:a3ea811f80f2 535 }
Helmut64 0:a3ea811f80f2 536
Helmut64 0:a3ea811f80f2 537 /* Force to full-speed */
Helmut64 0:a3ea811f80f2 538 HSUSBD->OPER = 0;//USBD_OPER_HISPDEN_Msk;
Helmut64 0:a3ea811f80f2 539
Helmut64 0:a3ea811f80f2 540 /* Set SE0 (disconnect) */
Helmut64 0:a3ea811f80f2 541 HSUSBD_SET_SE0();
Helmut64 0:a3ea811f80f2 542
Helmut64 0:a3ea811f80f2 543 NVIC_SetVector(USBD20_IRQn, (uint32_t) &_usbisr);
Helmut64 0:a3ea811f80f2 544 NVIC_EnableIRQ(USBD20_IRQn);
Helmut64 0:a3ea811f80f2 545 }
Helmut64 0:a3ea811f80f2 546
Helmut64 0:a3ea811f80f2 547 USBHAL::~USBHAL(void)
Helmut64 0:a3ea811f80f2 548 {
Helmut64 0:a3ea811f80f2 549 NVIC_DisableIRQ(USBD20_IRQn);
Helmut64 0:a3ea811f80f2 550 HSUSBD_SET_SE0();
Helmut64 0:a3ea811f80f2 551 HSUSBD_DISABLE_PHY();
Helmut64 0:a3ea811f80f2 552 }
Helmut64 0:a3ea811f80f2 553
Helmut64 0:a3ea811f80f2 554 void USBHAL::connect(void)
Helmut64 0:a3ea811f80f2 555 {
Helmut64 0:a3ea811f80f2 556 HSUSBD_ResetDMA();
Helmut64 0:a3ea811f80f2 557 HSUSBD_SET_ADDR(0);
Helmut64 0:a3ea811f80f2 558
Helmut64 0:a3ea811f80f2 559 /**
Helmut64 0:a3ea811f80f2 560 * Control Transfer Packet Size Constraints
Helmut64 0:a3ea811f80f2 561 * low-speed: 8
Helmut64 0:a3ea811f80f2 562 * full-speed: 8, 16, 32, 64
Helmut64 0:a3ea811f80f2 563 * high-speed: 64
Helmut64 0:a3ea811f80f2 564 */
Helmut64 0:a3ea811f80f2 565 /* Control endpoint */
Helmut64 0:a3ea811f80f2 566 HSUSBD_SetEpBufAddr(CEP, s_ep_buf_ind, MAX_PACKET_SIZE_EP0);
Helmut64 0:a3ea811f80f2 567 s_ep_buf_ind = MAX_PACKET_SIZE_EP0;
Helmut64 0:a3ea811f80f2 568
Helmut64 0:a3ea811f80f2 569 /* Enable USB/CEP interrupt */
Helmut64 0:a3ea811f80f2 570 HSUSBD_ENABLE_USB_INT(HSUSBD_GINTEN_USBIEN_Msk | HSUSBD_GINTEN_CEPIEN_Msk);
Helmut64 0:a3ea811f80f2 571 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk);
Helmut64 0:a3ea811f80f2 572
Helmut64 0:a3ea811f80f2 573 /* Enable BUS interrupt */
Helmut64 0:a3ea811f80f2 574 HSUSBD_ENABLE_BUS_INT(
Helmut64 0:a3ea811f80f2 575 HSUSBD_BUSINTEN_DMADONEIEN_Msk |
Helmut64 0:a3ea811f80f2 576 HSUSBD_BUSINTEN_RESUMEIEN_Msk |
Helmut64 0:a3ea811f80f2 577 HSUSBD_BUSINTEN_RSTIEN_Msk |
Helmut64 0:a3ea811f80f2 578 HSUSBD_BUSINTEN_VBUSDETIEN_Msk |
Helmut64 0:a3ea811f80f2 579 HSUSBD_BUSINTEN_SOFIEN_Msk
Helmut64 0:a3ea811f80f2 580 );
Helmut64 0:a3ea811f80f2 581
Helmut64 0:a3ea811f80f2 582 /* Clear SE0 (connect) */
Helmut64 0:a3ea811f80f2 583 HSUSBD_CLR_SE0();
Helmut64 0:a3ea811f80f2 584 }
Helmut64 0:a3ea811f80f2 585
Helmut64 0:a3ea811f80f2 586 void USBHAL::disconnect(void)
Helmut64 0:a3ea811f80f2 587 {
Helmut64 0:a3ea811f80f2 588 /* Set SE0 (disconnect) */
Helmut64 0:a3ea811f80f2 589 HSUSBD_SET_SE0();
Helmut64 0:a3ea811f80f2 590 }
Helmut64 0:a3ea811f80f2 591
Helmut64 0:a3ea811f80f2 592 void USBHAL::configureDevice(void)
Helmut64 0:a3ea811f80f2 593 {
Helmut64 0:a3ea811f80f2 594 /**
Helmut64 0:a3ea811f80f2 595 * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()).
Helmut64 0:a3ea811f80f2 596 * So we have the following USB buffer management policy:
Helmut64 0:a3ea811f80f2 597 * 1. Allocate for CEP on connect().
Helmut64 0:a3ea811f80f2 598 * 2. Allocate for EPX in realiseEndpoint().
Helmut64 0:a3ea811f80f2 599 * 3. Deallocate all except for CEP in unconfigureDevice().
Helmut64 0:a3ea811f80f2 600 */
Helmut64 0:a3ea811f80f2 601 }
Helmut64 0:a3ea811f80f2 602
Helmut64 0:a3ea811f80f2 603 void USBHAL::unconfigureDevice(void)
Helmut64 0:a3ea811f80f2 604 {
Helmut64 0:a3ea811f80f2 605 s_ep_buf_ind = MAX_PACKET_SIZE_EP0;
Helmut64 0:a3ea811f80f2 606 }
Helmut64 0:a3ea811f80f2 607
Helmut64 0:a3ea811f80f2 608 void USBHAL::setAddress(uint8_t address)
Helmut64 0:a3ea811f80f2 609 {
Helmut64 0:a3ea811f80f2 610 // NOTE: Delay address setting; otherwise, USB controller won't ack.
Helmut64 0:a3ea811f80f2 611 s_usb_addr = address;
Helmut64 0:a3ea811f80f2 612 }
Helmut64 0:a3ea811f80f2 613
Helmut64 0:a3ea811f80f2 614 void USBHAL::remoteWakeup(void)
Helmut64 0:a3ea811f80f2 615 {
Helmut64 0:a3ea811f80f2 616 HSUSBD->OPER |= HSUSBD_OPER_RESUMEEN_Msk;
Helmut64 0:a3ea811f80f2 617 }
Helmut64 0:a3ea811f80f2 618
Helmut64 0:a3ea811f80f2 619 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
Helmut64 0:a3ea811f80f2 620 {
Helmut64 0:a3ea811f80f2 621 uint32_t ep_type;
Helmut64 0:a3ea811f80f2 622 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 623
Helmut64 0:a3ea811f80f2 624 HSUSBD_SetEpBufAddr(ep_hw_index, s_ep_buf_ind, maxPacket);
Helmut64 0:a3ea811f80f2 625 s_ep_buf_ind += maxPacket;
Helmut64 0:a3ea811f80f2 626 HSUSBD_SET_MAX_PAYLOAD(ep_hw_index, maxPacket);
Helmut64 0:a3ea811f80f2 627
Helmut64 0:a3ea811f80f2 628 switch (NU_EP2EPL(endpoint)) {
Helmut64 0:a3ea811f80f2 629 case 1:
Helmut64 0:a3ea811f80f2 630 case 2:
Helmut64 0:a3ea811f80f2 631 ep_type = HSUSBD_EP_CFG_TYPE_INT;
Helmut64 0:a3ea811f80f2 632 break;
Helmut64 0:a3ea811f80f2 633
Helmut64 0:a3ea811f80f2 634 case 3:
Helmut64 0:a3ea811f80f2 635 case 4:
Helmut64 0:a3ea811f80f2 636 ep_type = HSUSBD_EP_CFG_TYPE_ISO;
Helmut64 0:a3ea811f80f2 637 break;
Helmut64 0:a3ea811f80f2 638
Helmut64 0:a3ea811f80f2 639 default:
Helmut64 0:a3ea811f80f2 640 ep_type = HSUSBD_EP_CFG_TYPE_BULK;
Helmut64 0:a3ea811f80f2 641 }
Helmut64 0:a3ea811f80f2 642 uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? HSUSBD_EP_CFG_DIR_IN : HSUSBD_EP_CFG_DIR_OUT;
Helmut64 0:a3ea811f80f2 643 HSUSBD_ConfigEp(ep_hw_index, NU_EP2EPL(endpoint), ep_type, ep_dir);
Helmut64 0:a3ea811f80f2 644
Helmut64 0:a3ea811f80f2 645 /* Enable USB/EPX interrupt */
Helmut64 0:a3ea811f80f2 646 // NOTE: Require USBD_GINTEN_EPAIE_Pos, USBD_GINTEN_EPBIE_Pos, ... USBD_GINTEN_EPLIE_Pos to be consecutive.
Helmut64 0:a3ea811f80f2 647 HSUSBD_ENABLE_USB_INT(HSUSBD->GINTEN | HSUSBD_GINTEN_USBIEN_Msk |
Helmut64 0:a3ea811f80f2 648 HSUSBD_GINTEN_CEPIEN_Msk |
Helmut64 0:a3ea811f80f2 649 1 << (ep_hw_index + HSUSBD_GINTEN_EPAIEN_Pos)); // Added USB/EPX interrupt
Helmut64 0:a3ea811f80f2 650
Helmut64 0:a3ea811f80f2 651 if (ep_dir == 0)
Helmut64 0:a3ea811f80f2 652 HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_RXPKIEN_Msk);
Helmut64 0:a3ea811f80f2 653 else
Helmut64 0:a3ea811f80f2 654 HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_TXPKIEN_Msk);
Helmut64 0:a3ea811f80f2 655 return true;
Helmut64 0:a3ea811f80f2 656 }
Helmut64 0:a3ea811f80f2 657
Helmut64 0:a3ea811f80f2 658 void USBHAL::EP0setup(uint8_t *buffer)
Helmut64 0:a3ea811f80f2 659 {
Helmut64 0:a3ea811f80f2 660 uint32_t sz;
Helmut64 0:a3ea811f80f2 661 endpointReadResult(EP0OUT, buffer, &sz);
Helmut64 0:a3ea811f80f2 662 }
Helmut64 0:a3ea811f80f2 663
Helmut64 0:a3ea811f80f2 664 void USBHAL::EP0read(void)
Helmut64 0:a3ea811f80f2 665 {
Helmut64 0:a3ea811f80f2 666 if (s_setup.wLength && ! (s_setup.bmRequestType & 0x80)) {
Helmut64 0:a3ea811f80f2 667 // Control OUT
Helmut64 0:a3ea811f80f2 668 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk | HSUSBD_CEPINTEN_RXPKIEN_Msk);
Helmut64 0:a3ea811f80f2 669 } else {
Helmut64 0:a3ea811f80f2 670 // Status stage
Helmut64 0:a3ea811f80f2 671 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk);
Helmut64 0:a3ea811f80f2 672 HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
Helmut64 0:a3ea811f80f2 673 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk);
Helmut64 0:a3ea811f80f2 674 }
Helmut64 0:a3ea811f80f2 675 }
Helmut64 0:a3ea811f80f2 676
Helmut64 0:a3ea811f80f2 677 void USBHAL::EP0readStage(void)
Helmut64 0:a3ea811f80f2 678 {
Helmut64 0:a3ea811f80f2 679 // N/A
Helmut64 0:a3ea811f80f2 680 }
Helmut64 0:a3ea811f80f2 681
Helmut64 0:a3ea811f80f2 682 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
Helmut64 0:a3ea811f80f2 683 {
Helmut64 0:a3ea811f80f2 684 uint32_t i;
Helmut64 0:a3ea811f80f2 685 uint32_t ceprxcnt = HSUSBD->CEPRXCNT;
Helmut64 0:a3ea811f80f2 686 for (i = 0; i < ceprxcnt; i ++)
Helmut64 0:a3ea811f80f2 687 *buffer ++ = HSUSBD->CEPDAT_BYTE;
Helmut64 0:a3ea811f80f2 688 return ceprxcnt;
Helmut64 0:a3ea811f80f2 689 }
Helmut64 0:a3ea811f80f2 690
Helmut64 0:a3ea811f80f2 691 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
Helmut64 0:a3ea811f80f2 692 {
Helmut64 0:a3ea811f80f2 693 if (buffer && size) {
Helmut64 0:a3ea811f80f2 694 g_usbd_CtrlInPointer = buffer;
Helmut64 0:a3ea811f80f2 695 g_usbd_CtrlInSize = size;
Helmut64 0:a3ea811f80f2 696 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk);
Helmut64 0:a3ea811f80f2 697 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk);
Helmut64 0:a3ea811f80f2 698 } else {
Helmut64 0:a3ea811f80f2 699 /* Status stage */
Helmut64 0:a3ea811f80f2 700 s_ctrlin_packetsize = 0;
Helmut64 0:a3ea811f80f2 701 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk);
Helmut64 0:a3ea811f80f2 702 HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR);
Helmut64 0:a3ea811f80f2 703 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk);
Helmut64 0:a3ea811f80f2 704 }
Helmut64 0:a3ea811f80f2 705 }
Helmut64 0:a3ea811f80f2 706
Helmut64 0:a3ea811f80f2 707 void USBHAL::EP0getWriteResult(void)
Helmut64 0:a3ea811f80f2 708 {
Helmut64 0:a3ea811f80f2 709 // N/A
Helmut64 0:a3ea811f80f2 710 }
Helmut64 0:a3ea811f80f2 711
Helmut64 0:a3ea811f80f2 712 void USBHAL::EP0stall(void)
Helmut64 0:a3ea811f80f2 713 {
Helmut64 0:a3ea811f80f2 714 stallEndpoint(EP0OUT);
Helmut64 0:a3ea811f80f2 715 }
Helmut64 0:a3ea811f80f2 716
Helmut64 0:a3ea811f80f2 717 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
Helmut64 0:a3ea811f80f2 718 {
Helmut64 0:a3ea811f80f2 719 return EP_PENDING;
Helmut64 0:a3ea811f80f2 720 }
Helmut64 0:a3ea811f80f2 721
Helmut64 0:a3ea811f80f2 722 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng
Helmut64 0:a3ea811f80f2 723 {
Helmut64 0:a3ea811f80f2 724 if(endpoint == EP0OUT) {
Helmut64 0:a3ea811f80f2 725 if (buffer) {
Helmut64 0:a3ea811f80f2 726 *((uint16_t *) (buffer + 0)) = (uint16_t) HSUSBD->SETUP1_0;
Helmut64 0:a3ea811f80f2 727 *((uint16_t *) (buffer + 2)) = (uint16_t) HSUSBD->SETUP3_2;
Helmut64 0:a3ea811f80f2 728 *((uint16_t *) (buffer + 4)) = (uint16_t) HSUSBD->SETUP5_4;
Helmut64 0:a3ea811f80f2 729 *((uint16_t *) (buffer + 6)) = (uint16_t) HSUSBD->SETUP7_6;
Helmut64 0:a3ea811f80f2 730 }
Helmut64 0:a3ea811f80f2 731
Helmut64 0:a3ea811f80f2 732 s_setup.bmRequestType = (uint8_t) (HSUSBD->SETUP1_0 & 0xff);
Helmut64 0:a3ea811f80f2 733 s_setup.bRequest = (int8_t) (HSUSBD->SETUP1_0 >> 8) & 0xff;
Helmut64 0:a3ea811f80f2 734 s_setup.wValue = (uint16_t) HSUSBD->SETUP3_2;
Helmut64 0:a3ea811f80f2 735 s_setup.wIndex = (uint16_t) HSUSBD->SETUP5_4;
Helmut64 0:a3ea811f80f2 736 s_setup.wLength = (uint16_t) HSUSBD->SETUP7_6;
Helmut64 0:a3ea811f80f2 737 } else {
Helmut64 0:a3ea811f80f2 738 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) {
Helmut64 0:a3ea811f80f2 739 while(1) {
Helmut64 0:a3ea811f80f2 740 if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk))
Helmut64 0:a3ea811f80f2 741 break;
Helmut64 0:a3ea811f80f2 742 else if (!HSUSBD_IS_ATTACHED())
Helmut64 0:a3ea811f80f2 743 break;
Helmut64 0:a3ea811f80f2 744 }
Helmut64 0:a3ea811f80f2 745 gEpReadCnt = HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint));
Helmut64 0:a3ea811f80f2 746 if(gEpReadCnt == 0) {
Helmut64 0:a3ea811f80f2 747 *bytesRead = 0;
Helmut64 0:a3ea811f80f2 748 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 749 }
Helmut64 0:a3ea811f80f2 750 s_ep_compl |= (1 << NU_EP2EPL(endpoint));
Helmut64 0:a3ea811f80f2 751 HSUSBD_SET_DMA_LEN(gEpReadCnt);
Helmut64 0:a3ea811f80f2 752 HSUSBD_SET_DMA_ADDR((uint32_t)buffer);
Helmut64 0:a3ea811f80f2 753 HSUSBD_SET_DMA_WRITE(NU_EP2EPL(endpoint));
Helmut64 0:a3ea811f80f2 754 HSUSBD_ENABLE_DMA();
Helmut64 0:a3ea811f80f2 755 return EP_PENDING;;
Helmut64 0:a3ea811f80f2 756
Helmut64 0:a3ea811f80f2 757 } else {
Helmut64 0:a3ea811f80f2 758 if ((HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk))
Helmut64 0:a3ea811f80f2 759 return EP_PENDING;;
Helmut64 0:a3ea811f80f2 760
Helmut64 0:a3ea811f80f2 761 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk);
Helmut64 0:a3ea811f80f2 762 s_ep_compl &= ~(1 << NU_EP2EPL(endpoint));
Helmut64 0:a3ea811f80f2 763 *bytesRead = gEpReadCnt;
Helmut64 0:a3ea811f80f2 764 }
Helmut64 0:a3ea811f80f2 765 }
Helmut64 0:a3ea811f80f2 766 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 767 }
Helmut64 0:a3ea811f80f2 768
Helmut64 0:a3ea811f80f2 769
Helmut64 0:a3ea811f80f2 770 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer)
Helmut64 0:a3ea811f80f2 771 {
Helmut64 0:a3ea811f80f2 772 return 0;
Helmut64 0:a3ea811f80f2 773 }
Helmut64 0:a3ea811f80f2 774
Helmut64 0:a3ea811f80f2 775 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
Helmut64 0:a3ea811f80f2 776 {
Helmut64 0:a3ea811f80f2 777 uint32_t ep_logic_index = NU_EP2EPL(endpoint);
Helmut64 0:a3ea811f80f2 778 if(ep_logic_index == 0)
Helmut64 0:a3ea811f80f2 779 return EP_INVALID;
Helmut64 0:a3ea811f80f2 780 else {
Helmut64 0:a3ea811f80f2 781 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 782 uint32_t mps = HSUSBD_GET_EP_MAX_PAYLOAD(ep_hw_index);
Helmut64 0:a3ea811f80f2 783 if (size > mps) {
Helmut64 0:a3ea811f80f2 784 return EP_INVALID;
Helmut64 0:a3ea811f80f2 785 }
Helmut64 0:a3ea811f80f2 786 if(size < mps)
Helmut64 0:a3ea811f80f2 787 g_usbd_ShortPacket = 1;
Helmut64 0:a3ea811f80f2 788 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) {
Helmut64 0:a3ea811f80f2 789 s_ep_compl |= (1 << ep_logic_index);
Helmut64 0:a3ea811f80f2 790
Helmut64 0:a3ea811f80f2 791 while(1) {
Helmut64 0:a3ea811f80f2 792 if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk))
Helmut64 0:a3ea811f80f2 793 break;
Helmut64 0:a3ea811f80f2 794 else if (!HSUSBD_IS_ATTACHED())
Helmut64 0:a3ea811f80f2 795 break;
Helmut64 0:a3ea811f80f2 796 }
Helmut64 0:a3ea811f80f2 797 HSUSBD_SET_DMA_LEN(size);
Helmut64 0:a3ea811f80f2 798 HSUSBD_SET_DMA_ADDR((uint32_t)data);
Helmut64 0:a3ea811f80f2 799 HSUSBD_SET_DMA_READ(ep_logic_index);
Helmut64 0:a3ea811f80f2 800 HSUSBD_ENABLE_DMA();
Helmut64 0:a3ea811f80f2 801 }
Helmut64 0:a3ea811f80f2 802 }
Helmut64 0:a3ea811f80f2 803 return EP_PENDING;
Helmut64 0:a3ea811f80f2 804 }
Helmut64 0:a3ea811f80f2 805
Helmut64 0:a3ea811f80f2 806 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 807 {
Helmut64 0:a3ea811f80f2 808 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
Helmut64 0:a3ea811f80f2 809 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 810 else {
Helmut64 0:a3ea811f80f2 811 if((HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint))) == 0 && !(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) {
Helmut64 0:a3ea811f80f2 812 s_ep_compl &= ~(s_ep_compl & (1 << NU_EP2EPL(endpoint)));
Helmut64 0:a3ea811f80f2 813 return EP_COMPLETED;
Helmut64 0:a3ea811f80f2 814 }
Helmut64 0:a3ea811f80f2 815 }
Helmut64 0:a3ea811f80f2 816 return EP_PENDING;
Helmut64 0:a3ea811f80f2 817 }
Helmut64 0:a3ea811f80f2 818
Helmut64 0:a3ea811f80f2 819 void USBHAL::stallEndpoint(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 820 {
Helmut64 0:a3ea811f80f2 821 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 822 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 823 return;
Helmut64 0:a3ea811f80f2 824 HSUSBD_SetStall(ep_hw_index);
Helmut64 0:a3ea811f80f2 825 }
Helmut64 0:a3ea811f80f2 826
Helmut64 0:a3ea811f80f2 827 void USBHAL::unstallEndpoint(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 828 {
Helmut64 0:a3ea811f80f2 829 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 830 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 831 return;
Helmut64 0:a3ea811f80f2 832 HSUSBD_ClearStall(ep_hw_index);
Helmut64 0:a3ea811f80f2 833 }
Helmut64 0:a3ea811f80f2 834
Helmut64 0:a3ea811f80f2 835 bool USBHAL::getEndpointStallState(uint8_t endpoint)
Helmut64 0:a3ea811f80f2 836 {
Helmut64 0:a3ea811f80f2 837 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Helmut64 0:a3ea811f80f2 838 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Helmut64 0:a3ea811f80f2 839 return false;
Helmut64 0:a3ea811f80f2 840 return HSUSBD_GetStall(ep_hw_index) ? 1 : 0;
Helmut64 0:a3ea811f80f2 841 }
Helmut64 0:a3ea811f80f2 842
Helmut64 0:a3ea811f80f2 843 void USBHAL::_usbisr(void)
Helmut64 0:a3ea811f80f2 844 {
Helmut64 0:a3ea811f80f2 845 MBED_ASSERT(instance);
Helmut64 0:a3ea811f80f2 846 instance->usbisr();
Helmut64 0:a3ea811f80f2 847 }
Helmut64 0:a3ea811f80f2 848
Helmut64 0:a3ea811f80f2 849 void USBHAL::usbisr(void)
Helmut64 0:a3ea811f80f2 850 {
Helmut64 0:a3ea811f80f2 851 uint32_t gintsts = HSUSBD->GINTSTS & HSUSBD->GINTEN;
Helmut64 0:a3ea811f80f2 852 if (! gintsts)
Helmut64 0:a3ea811f80f2 853 return;
Helmut64 0:a3ea811f80f2 854
Helmut64 0:a3ea811f80f2 855 if (gintsts & HSUSBD_GINTSTS_USBIF_Msk) {
Helmut64 0:a3ea811f80f2 856 uint32_t busintsts = HSUSBD->BUSINTSTS & HSUSBD->BUSINTEN;
Helmut64 0:a3ea811f80f2 857
Helmut64 0:a3ea811f80f2 858 /* SOF */
Helmut64 0:a3ea811f80f2 859 if (busintsts & HSUSBD_BUSINTSTS_SOFIF_Msk) {
Helmut64 0:a3ea811f80f2 860 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SOFIF_Msk);
Helmut64 0:a3ea811f80f2 861 // TODO
Helmut64 0:a3ea811f80f2 862 SOF(HSUSBD->FRAMECNT >> 3);
Helmut64 0:a3ea811f80f2 863 }
Helmut64 0:a3ea811f80f2 864
Helmut64 0:a3ea811f80f2 865 /* Reset */
Helmut64 0:a3ea811f80f2 866 if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) {
Helmut64 0:a3ea811f80f2 867 connect();
Helmut64 0:a3ea811f80f2 868 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RSTIF_Msk);
Helmut64 0:a3ea811f80f2 869 HSUSBD_CLR_CEP_INT_FLAG(0x1ffc);
Helmut64 0:a3ea811f80f2 870 }
Helmut64 0:a3ea811f80f2 871
Helmut64 0:a3ea811f80f2 872 /* Resume */
Helmut64 0:a3ea811f80f2 873 if (busintsts & HSUSBD_BUSINTSTS_RESUMEIF_Msk) {
Helmut64 0:a3ea811f80f2 874 HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk|HSUSBD_BUSINTEN_SUSPENDIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk);
Helmut64 0:a3ea811f80f2 875 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RESUMEIF_Msk);
Helmut64 0:a3ea811f80f2 876 }
Helmut64 0:a3ea811f80f2 877
Helmut64 0:a3ea811f80f2 878 /* Suspend */
Helmut64 0:a3ea811f80f2 879 if (busintsts & HSUSBD_BUSINTSTS_SUSPENDIF_Msk) {
Helmut64 0:a3ea811f80f2 880 HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk | HSUSBD_BUSINTEN_RESUMEIEN_Msk |HSUSBD_BUSINTEN_SOFIEN_Msk);
Helmut64 0:a3ea811f80f2 881 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SUSPENDIF_Msk);
Helmut64 0:a3ea811f80f2 882 }
Helmut64 0:a3ea811f80f2 883
Helmut64 0:a3ea811f80f2 884 /* High-speed */
Helmut64 0:a3ea811f80f2 885 if (busintsts & HSUSBD_BUSINTSTS_HISPDIF_Msk) {
Helmut64 0:a3ea811f80f2 886 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
Helmut64 0:a3ea811f80f2 887 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_HISPDIF_Msk);
Helmut64 0:a3ea811f80f2 888 }
Helmut64 0:a3ea811f80f2 889
Helmut64 0:a3ea811f80f2 890 /* DMA */
Helmut64 0:a3ea811f80f2 891 if (busintsts & HSUSBD_BUSINTSTS_DMADONEIF_Msk) {
Helmut64 0:a3ea811f80f2 892 if(HSUSBD->DMACTL & 0x10) { /* IN - Read */
Helmut64 0:a3ea811f80f2 893 if(g_usbd_ShortPacket) {
Helmut64 0:a3ea811f80f2 894 uint32_t ep_hw_index = NU_EPL2EPH((HSUSBD->DMACTL & 0xF));
Helmut64 0:a3ea811f80f2 895 HSUSBD_SET_EP_SHORT_PACKET(ep_hw_index);
Helmut64 0:a3ea811f80f2 896 g_usbd_ShortPacket = 0;
Helmut64 0:a3ea811f80f2 897 }
Helmut64 0:a3ea811f80f2 898 }
Helmut64 0:a3ea811f80f2 899 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk);
Helmut64 0:a3ea811f80f2 900 }
Helmut64 0:a3ea811f80f2 901
Helmut64 0:a3ea811f80f2 902 /* PHY clock available */
Helmut64 0:a3ea811f80f2 903 if (busintsts & HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk) {
Helmut64 0:a3ea811f80f2 904 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk);
Helmut64 0:a3ea811f80f2 905 }
Helmut64 0:a3ea811f80f2 906
Helmut64 0:a3ea811f80f2 907 /* VBUS plug-in */
Helmut64 0:a3ea811f80f2 908 if (busintsts & HSUSBD_BUSINTSTS_VBUSDETIF_Msk) {
Helmut64 0:a3ea811f80f2 909 if (HSUSBD_IS_ATTACHED()) {
Helmut64 0:a3ea811f80f2 910 // USB plug-in
Helmut64 0:a3ea811f80f2 911 HSUSBD_ENABLE_USB();
Helmut64 0:a3ea811f80f2 912 } else {
Helmut64 0:a3ea811f80f2 913 // USB unplug-out
Helmut64 0:a3ea811f80f2 914 HSUSBD_DISABLE_USB();
Helmut64 0:a3ea811f80f2 915 }
Helmut64 0:a3ea811f80f2 916 HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_VBUSDETIF_Msk);
Helmut64 0:a3ea811f80f2 917 }
Helmut64 0:a3ea811f80f2 918 }
Helmut64 0:a3ea811f80f2 919
Helmut64 0:a3ea811f80f2 920 /* CEP interrupts */
Helmut64 0:a3ea811f80f2 921 if (gintsts & HSUSBD_GINTSTS_CEPIF_Msk) {
Helmut64 0:a3ea811f80f2 922 uint32_t cepintsts = HSUSBD->CEPINTSTS & HSUSBD->CEPINTEN;
Helmut64 0:a3ea811f80f2 923
Helmut64 0:a3ea811f80f2 924 /* SETUP token packet */
Helmut64 0:a3ea811f80f2 925 if (cepintsts & HSUSBD_CEPINTSTS_SETUPTKIF_Msk) {
Helmut64 0:a3ea811f80f2 926 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPTKIF_Msk);
Helmut64 0:a3ea811f80f2 927 return;
Helmut64 0:a3ea811f80f2 928 }
Helmut64 0:a3ea811f80f2 929
Helmut64 0:a3ea811f80f2 930 /* SETUP transaction */
Helmut64 0:a3ea811f80f2 931 if (cepintsts & HSUSBD_CEPINTSTS_SETUPPKIF_Msk) {
Helmut64 0:a3ea811f80f2 932 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk);
Helmut64 0:a3ea811f80f2 933 EP0setupCallback();
Helmut64 0:a3ea811f80f2 934 return;
Helmut64 0:a3ea811f80f2 935 }
Helmut64 0:a3ea811f80f2 936
Helmut64 0:a3ea811f80f2 937 /* OUT token packet */
Helmut64 0:a3ea811f80f2 938 if (cepintsts & HSUSBD_CEPINTSTS_OUTTKIF_Msk) {
Helmut64 0:a3ea811f80f2 939 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_OUTTKIF_Msk);
Helmut64 0:a3ea811f80f2 940 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk);
Helmut64 0:a3ea811f80f2 941 return;
Helmut64 0:a3ea811f80f2 942 }
Helmut64 0:a3ea811f80f2 943
Helmut64 0:a3ea811f80f2 944 /* IN token packet */
Helmut64 0:a3ea811f80f2 945 if (cepintsts & HSUSBD_CEPINTSTS_INTKIF_Msk) {
Helmut64 0:a3ea811f80f2 946 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk);
Helmut64 0:a3ea811f80f2 947 if (!(cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk)) {
Helmut64 0:a3ea811f80f2 948 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk);
Helmut64 0:a3ea811f80f2 949 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk);
Helmut64 0:a3ea811f80f2 950 HSUSBD_CtrlInput();
Helmut64 0:a3ea811f80f2 951 } else {
Helmut64 0:a3ea811f80f2 952 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk);
Helmut64 0:a3ea811f80f2 953 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk);
Helmut64 0:a3ea811f80f2 954 }
Helmut64 0:a3ea811f80f2 955 return;
Helmut64 0:a3ea811f80f2 956 }
Helmut64 0:a3ea811f80f2 957
Helmut64 0:a3ea811f80f2 958 /* PING packet */
Helmut64 0:a3ea811f80f2 959 if (cepintsts & HSUSBD_CEPINTSTS_PINGIF_Msk) {
Helmut64 0:a3ea811f80f2 960 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_PINGIF_Msk);
Helmut64 0:a3ea811f80f2 961 return;
Helmut64 0:a3ea811f80f2 962 }
Helmut64 0:a3ea811f80f2 963
Helmut64 0:a3ea811f80f2 964 /* IN transaction */
Helmut64 0:a3ea811f80f2 965 if (cepintsts & HSUSBD_CEPINTSTS_TXPKIF_Msk) {
Helmut64 0:a3ea811f80f2 966 EP0in();
Helmut64 0:a3ea811f80f2 967 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk);
Helmut64 0:a3ea811f80f2 968 return;
Helmut64 0:a3ea811f80f2 969 }
Helmut64 0:a3ea811f80f2 970
Helmut64 0:a3ea811f80f2 971 /* OUT transaction */
Helmut64 0:a3ea811f80f2 972 if (cepintsts & HSUSBD_CEPINTSTS_RXPKIF_Msk) {
Helmut64 0:a3ea811f80f2 973 EP0out();
Helmut64 0:a3ea811f80f2 974 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_RXPKIF_Msk);
Helmut64 0:a3ea811f80f2 975 return;
Helmut64 0:a3ea811f80f2 976 }
Helmut64 0:a3ea811f80f2 977
Helmut64 0:a3ea811f80f2 978 /* NAK handshake packet */
Helmut64 0:a3ea811f80f2 979 if (cepintsts & HSUSBD_CEPINTSTS_NAKIF_Msk) {
Helmut64 0:a3ea811f80f2 980 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_NAKIF_Msk);
Helmut64 0:a3ea811f80f2 981 return;
Helmut64 0:a3ea811f80f2 982 }
Helmut64 0:a3ea811f80f2 983
Helmut64 0:a3ea811f80f2 984 /* STALL handshake packet */
Helmut64 0:a3ea811f80f2 985 if (cepintsts & HSUSBD_CEPINTSTS_STALLIF_Msk) {
Helmut64 0:a3ea811f80f2 986 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STALLIF_Msk);
Helmut64 0:a3ea811f80f2 987 return;
Helmut64 0:a3ea811f80f2 988 }
Helmut64 0:a3ea811f80f2 989
Helmut64 0:a3ea811f80f2 990 /* ERR special packet */
Helmut64 0:a3ea811f80f2 991 if (cepintsts & HSUSBD_CEPINTSTS_ERRIF_Msk) {
Helmut64 0:a3ea811f80f2 992 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_ERRIF_Msk);
Helmut64 0:a3ea811f80f2 993 return;
Helmut64 0:a3ea811f80f2 994 }
Helmut64 0:a3ea811f80f2 995
Helmut64 0:a3ea811f80f2 996 /* Status stage transaction */
Helmut64 0:a3ea811f80f2 997 if (cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk) {
Helmut64 0:a3ea811f80f2 998 if (s_usb_addr) {
Helmut64 0:a3ea811f80f2 999 HSUSBD_SET_ADDR(s_usb_addr);
Helmut64 0:a3ea811f80f2 1000 s_usb_addr = 0;
Helmut64 0:a3ea811f80f2 1001 }
Helmut64 0:a3ea811f80f2 1002 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk);
Helmut64 0:a3ea811f80f2 1003 HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk);
Helmut64 0:a3ea811f80f2 1004 return;
Helmut64 0:a3ea811f80f2 1005 }
Helmut64 0:a3ea811f80f2 1006
Helmut64 0:a3ea811f80f2 1007 /* Buffer Full */
Helmut64 0:a3ea811f80f2 1008 if (cepintsts & HSUSBD_CEPINTSTS_BUFFULLIF_Msk) {
Helmut64 0:a3ea811f80f2 1009 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFFULLIF_Msk);
Helmut64 0:a3ea811f80f2 1010 return;
Helmut64 0:a3ea811f80f2 1011 }
Helmut64 0:a3ea811f80f2 1012
Helmut64 0:a3ea811f80f2 1013 /* Buffer Empty */
Helmut64 0:a3ea811f80f2 1014 if (cepintsts & HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk) {
Helmut64 0:a3ea811f80f2 1015 HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk);
Helmut64 0:a3ea811f80f2 1016 return;
Helmut64 0:a3ea811f80f2 1017 }
Helmut64 0:a3ea811f80f2 1018 }
Helmut64 0:a3ea811f80f2 1019 /* EPA, EPB, EPC, ... EPL interrupts */
Helmut64 0:a3ea811f80f2 1020 uint32_t gintsts_epx = gintsts >> 2;
Helmut64 0:a3ea811f80f2 1021 uint32_t ep_hw_index = 0;
Helmut64 0:a3ea811f80f2 1022 while (gintsts_epx) {
Helmut64 0:a3ea811f80f2 1023 if(gintsts_epx & 0x01) {
Helmut64 0:a3ea811f80f2 1024 uint32_t epxintsts = HSUSBD_GET_EP_INT_FLAG(ep_hw_index) & HSUSBD_GET_EP_INT_EN(ep_hw_index);
Helmut64 0:a3ea811f80f2 1025
Helmut64 0:a3ea811f80f2 1026 HSUSBD_CLR_EP_INT_FLAG(ep_hw_index, epxintsts);
Helmut64 0:a3ea811f80f2 1027
Helmut64 0:a3ea811f80f2 1028 /* Buffer Full */
Helmut64 0:a3ea811f80f2 1029 if (epxintsts & HSUSBD_EPINTSTS_BUFFULLIF_Msk) {
Helmut64 0:a3ea811f80f2 1030 }
Helmut64 0:a3ea811f80f2 1031
Helmut64 0:a3ea811f80f2 1032 /* Buffer Empty */
Helmut64 0:a3ea811f80f2 1033 if (epxintsts & HSUSBD_EPINTSTS_BUFEMPTYIF_Msk) {
Helmut64 0:a3ea811f80f2 1034 }
Helmut64 0:a3ea811f80f2 1035
Helmut64 0:a3ea811f80f2 1036 /* Short Packet Transferred */
Helmut64 0:a3ea811f80f2 1037 if (epxintsts & HSUSBD_EPINTSTS_SHORTTXIF_Msk) {
Helmut64 0:a3ea811f80f2 1038 }
Helmut64 0:a3ea811f80f2 1039
Helmut64 0:a3ea811f80f2 1040 /* Data Packet Transmitted */
Helmut64 0:a3ea811f80f2 1041 if (epxintsts & HSUSBD_EPINTSTS_TXPKIF_Msk) {
Helmut64 0:a3ea811f80f2 1042 s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index)));
Helmut64 0:a3ea811f80f2 1043 if ((instance->*(epCallback[ep_hw_index]))()) {
Helmut64 0:a3ea811f80f2 1044 }
Helmut64 0:a3ea811f80f2 1045 }
Helmut64 0:a3ea811f80f2 1046
Helmut64 0:a3ea811f80f2 1047 /* Data Packet Received */
Helmut64 0:a3ea811f80f2 1048 if (epxintsts & HSUSBD_EPINTSTS_RXPKIF_Msk) {
Helmut64 0:a3ea811f80f2 1049 if ((instance->*(epCallback[ep_hw_index]))()) {
Helmut64 0:a3ea811f80f2 1050
Helmut64 0:a3ea811f80f2 1051 }
Helmut64 0:a3ea811f80f2 1052 }
Helmut64 0:a3ea811f80f2 1053
Helmut64 0:a3ea811f80f2 1054 /* OUT token packet */
Helmut64 0:a3ea811f80f2 1055 if (epxintsts & HSUSBD_EPINTSTS_OUTTKIF_Msk) {
Helmut64 0:a3ea811f80f2 1056 }
Helmut64 0:a3ea811f80f2 1057
Helmut64 0:a3ea811f80f2 1058 /* IN token packet */
Helmut64 0:a3ea811f80f2 1059 if (epxintsts & HSUSBD_EPINTSTS_INTKIF_Msk) {
Helmut64 0:a3ea811f80f2 1060 }
Helmut64 0:a3ea811f80f2 1061
Helmut64 0:a3ea811f80f2 1062 /* PING packet */
Helmut64 0:a3ea811f80f2 1063 if (epxintsts & HSUSBD_EPINTSTS_PINGIF_Msk) {
Helmut64 0:a3ea811f80f2 1064 }
Helmut64 0:a3ea811f80f2 1065
Helmut64 0:a3ea811f80f2 1066 /* NAK handshake packet sent to Host */
Helmut64 0:a3ea811f80f2 1067 if (epxintsts & HSUSBD_EPINTSTS_NAKIF_Msk) {
Helmut64 0:a3ea811f80f2 1068 }
Helmut64 0:a3ea811f80f2 1069
Helmut64 0:a3ea811f80f2 1070 /* STALL handshake packet sent to Host */
Helmut64 0:a3ea811f80f2 1071 if (epxintsts & HSUSBD_EPINTSTS_STALLIF_Msk) {
Helmut64 0:a3ea811f80f2 1072 }
Helmut64 0:a3ea811f80f2 1073
Helmut64 0:a3ea811f80f2 1074 /* NYET handshake packet sent to Host */
Helmut64 0:a3ea811f80f2 1075 if (epxintsts & HSUSBD_EPINTSTS_NYETIF_Msk) {
Helmut64 0:a3ea811f80f2 1076 }
Helmut64 0:a3ea811f80f2 1077
Helmut64 0:a3ea811f80f2 1078 /* ERR packet sent to Host */
Helmut64 0:a3ea811f80f2 1079 if (epxintsts & HSUSBD_EPINTSTS_ERRIF_Msk) {
Helmut64 0:a3ea811f80f2 1080 }
Helmut64 0:a3ea811f80f2 1081
Helmut64 0:a3ea811f80f2 1082 /* Bulk Out Short Packet Received */
Helmut64 0:a3ea811f80f2 1083 if (epxintsts & HSUSBD_EPINTSTS_SHORTRXIF_Msk) {
Helmut64 0:a3ea811f80f2 1084 }
Helmut64 0:a3ea811f80f2 1085 }
Helmut64 0:a3ea811f80f2 1086 gintsts_epx = gintsts_epx >> 1;
Helmut64 0:a3ea811f80f2 1087 ep_hw_index++;
Helmut64 0:a3ea811f80f2 1088 }
Helmut64 0:a3ea811f80f2 1089 }
Helmut64 0:a3ea811f80f2 1090 #endif
Helmut64 0:a3ea811f80f2 1091
Helmut64 0:a3ea811f80f2 1092 #endif
Helmut64 0:a3ea811f80f2 1093