USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
muraguchi
Date:
Wed Sep 15 16:31:51 2021 +0000
Revision:
73:72808bd55ce2
Parent:
71:53949e6131f6
AirioBase + 2 chip PicoSSD board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 71:53949e6131f6 1 /* mbed Microcontroller Library
Kojto 71:53949e6131f6 2 * Copyright (c) 2015-2016 Nuvoton
Kojto 71:53949e6131f6 3 *
Kojto 71:53949e6131f6 4 * Licensed under the Apache License, Version 2.0 (the "License");
Kojto 71:53949e6131f6 5 * you may not use this file except in compliance with the License.
Kojto 71:53949e6131f6 6 * You may obtain a copy of the License at
Kojto 71:53949e6131f6 7 *
Kojto 71:53949e6131f6 8 * http://www.apache.org/licenses/LICENSE-2.0
Kojto 71:53949e6131f6 9 *
Kojto 71:53949e6131f6 10 * Unless required by applicable law or agreed to in writing, software
Kojto 71:53949e6131f6 11 * distributed under the License is distributed on an "AS IS" BASIS,
Kojto 71:53949e6131f6 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Kojto 71:53949e6131f6 13 * See the License for the specific language governing permissions and
Kojto 71:53949e6131f6 14 * limitations under the License.
Kojto 71:53949e6131f6 15 */
Kojto 71:53949e6131f6 16
Kojto 71:53949e6131f6 17 #if defined(TARGET_NUMAKER_PFM_M453)
Kojto 71:53949e6131f6 18
Kojto 71:53949e6131f6 19 #include "USBHAL.h"
Kojto 71:53949e6131f6 20 #include "M451Series.h"
Kojto 71:53949e6131f6 21 #include "pinmap.h"
Kojto 71:53949e6131f6 22
Kojto 71:53949e6131f6 23 /**
Kojto 71:53949e6131f6 24 * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN.
Kojto 71:53949e6131f6 25 * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC.
Kojto 71:53949e6131f6 26 */
Kojto 71:53949e6131f6 27
Kojto 71:53949e6131f6 28 USBHAL * USBHAL::instance;
Kojto 71:53949e6131f6 29
Kojto 71:53949e6131f6 30 /* Global variables for Control Pipe */
Kojto 71:53949e6131f6 31 extern uint8_t g_usbd_SetupPacket[]; /*!< Setup packet buffer */
Kojto 71:53949e6131f6 32
Kojto 71:53949e6131f6 33 static volatile uint32_t s_ep_compl = 0;
Kojto 71:53949e6131f6 34 static volatile uint32_t s_ep_buf_ind = 8;
Kojto 71:53949e6131f6 35 static volatile uint8_t s_usb_addr = 0;
Kojto 71:53949e6131f6 36 static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1};
Kojto 71:53949e6131f6 37 static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0};
Kojto 71:53949e6131f6 38
Kojto 71:53949e6131f6 39 extern volatile uint8_t *g_usbd_CtrlInPointer;
Kojto 71:53949e6131f6 40 extern volatile uint32_t g_usbd_CtrlInSize;
Kojto 71:53949e6131f6 41 extern volatile uint8_t *g_usbd_CtrlOutPointer;
Kojto 71:53949e6131f6 42 extern volatile uint32_t g_usbd_CtrlOutSize;
Kojto 71:53949e6131f6 43 extern volatile uint32_t g_usbd_CtrlOutSizeLimit;
Kojto 71:53949e6131f6 44 extern volatile uint32_t g_usbd_UsbConfig;
Kojto 71:53949e6131f6 45 extern volatile uint32_t g_usbd_CtrlMaxPktSize;
Kojto 71:53949e6131f6 46 extern volatile uint32_t g_usbd_UsbAltInterface;
Kojto 71:53949e6131f6 47 volatile uint32_t g_usbd_CepTransferLen = 0;
Kojto 71:53949e6131f6 48 volatile uint32_t frame_cnt = 0;
Kojto 71:53949e6131f6 49 USBHAL::USBHAL(void)
Kojto 71:53949e6131f6 50 {
Kojto 71:53949e6131f6 51 SYS_UnlockReg();
Kojto 71:53949e6131f6 52
Kojto 71:53949e6131f6 53 s_ep_buf_ind = 8;
Kojto 71:53949e6131f6 54
Kojto 71:53949e6131f6 55 memset(epCallback, 0x00, sizeof (epCallback));
Kojto 71:53949e6131f6 56 epCallback[0] = &USBHAL::EP1_OUT_callback;
Kojto 71:53949e6131f6 57 epCallback[1] = &USBHAL::EP2_IN_callback;
Kojto 71:53949e6131f6 58 epCallback[2] = &USBHAL::EP3_OUT_callback;
Kojto 71:53949e6131f6 59 epCallback[3] = &USBHAL::EP4_IN_callback;
Kojto 71:53949e6131f6 60 epCallback[4] = &USBHAL::EP5_OUT_callback;
Kojto 71:53949e6131f6 61 epCallback[5] = &USBHAL::EP6_IN_callback;
Kojto 71:53949e6131f6 62
Kojto 71:53949e6131f6 63 instance = this;
Kojto 71:53949e6131f6 64 /* Enable USBD module clock */
Kojto 71:53949e6131f6 65 CLK_EnableModuleClock(USBD_MODULE);
Kojto 71:53949e6131f6 66
Kojto 71:53949e6131f6 67 CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV0_USB(3));
Kojto 71:53949e6131f6 68
Kojto 71:53949e6131f6 69 /* Enable USB LDO33 */
Kojto 71:53949e6131f6 70 SYS->USBPHY = SYS_USBPHY_LDO33EN_Msk;
Kojto 71:53949e6131f6 71
Kojto 71:53949e6131f6 72 /* Initial USB engine */
Kojto 71:53949e6131f6 73 USBD->ATTR = 0x7D0;
Kojto 71:53949e6131f6 74
Kojto 71:53949e6131f6 75 /* Set SE0 (disconnect) */
Kojto 71:53949e6131f6 76 USBD_SET_SE0();
Kojto 71:53949e6131f6 77
Kojto 71:53949e6131f6 78 //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr);
Kojto 71:53949e6131f6 79 NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr);
Kojto 71:53949e6131f6 80 NVIC_EnableIRQ(USBD_IRQn);
Kojto 71:53949e6131f6 81 }
Kojto 71:53949e6131f6 82
Kojto 71:53949e6131f6 83 USBHAL::~USBHAL(void)
Kojto 71:53949e6131f6 84 {
Kojto 71:53949e6131f6 85 NVIC_DisableIRQ(USBD_IRQn);
Kojto 71:53949e6131f6 86 USBD_SET_SE0();
Kojto 71:53949e6131f6 87 USBD_DISABLE_PHY();
Kojto 71:53949e6131f6 88 }
Kojto 71:53949e6131f6 89
Kojto 71:53949e6131f6 90 void USBHAL::connect(void)
Kojto 71:53949e6131f6 91 {
Kojto 71:53949e6131f6 92 USBD->STBUFSEG = 0;
Kojto 71:53949e6131f6 93 frame_cnt = 0;
Kojto 71:53949e6131f6 94 /* EP0 ==> control IN endpoint, address 0 */
Kojto 71:53949e6131f6 95 USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
Kojto 71:53949e6131f6 96 /* Buffer range for EP0 */
Kojto 71:53949e6131f6 97 USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind);
Kojto 71:53949e6131f6 98
Kojto 71:53949e6131f6 99 /* EP1 ==> control OUT endpoint, address 0 */
Kojto 71:53949e6131f6 100 USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
Kojto 71:53949e6131f6 101 /* Buffer range for EP1 */
Kojto 71:53949e6131f6 102 USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind);
Kojto 71:53949e6131f6 103
Kojto 71:53949e6131f6 104 s_ep_buf_ind += MAX_PACKET_SIZE_EP0;
Kojto 71:53949e6131f6 105
Kojto 71:53949e6131f6 106 /* Disable software-disconnect function */
Kojto 71:53949e6131f6 107 USBD_CLR_SE0();
Kojto 71:53949e6131f6 108
Kojto 71:53949e6131f6 109 /* Clear USB-related interrupts before enable interrupt */
Kojto 71:53949e6131f6 110 USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
Kojto 71:53949e6131f6 111
Kojto 71:53949e6131f6 112 /* Enable USB-related interrupts. */
Kojto 71:53949e6131f6 113 USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
Kojto 71:53949e6131f6 114 }
Kojto 71:53949e6131f6 115
Kojto 71:53949e6131f6 116 void USBHAL::disconnect(void)
Kojto 71:53949e6131f6 117 {
Kojto 71:53949e6131f6 118 /* Set SE0 (disconnect) */
Kojto 71:53949e6131f6 119 USBD_SET_SE0();
Kojto 71:53949e6131f6 120 }
Kojto 71:53949e6131f6 121
Kojto 71:53949e6131f6 122 void USBHAL::configureDevice(void)
Kojto 71:53949e6131f6 123 {
Kojto 71:53949e6131f6 124 /**
Kojto 71:53949e6131f6 125 * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()).
Kojto 71:53949e6131f6 126 * So we have the following USB buffer management policy:
Kojto 71:53949e6131f6 127 * 1. Allocate for CEP on connect().
Kojto 71:53949e6131f6 128 * 2. Allocate for EPX in realiseEndpoint().
Kojto 71:53949e6131f6 129 * 3. Deallocate all except for CEP in unconfigureDevice().
Kojto 71:53949e6131f6 130 */
Kojto 71:53949e6131f6 131 }
Kojto 71:53949e6131f6 132
Kojto 71:53949e6131f6 133 void USBHAL::unconfigureDevice(void)
Kojto 71:53949e6131f6 134 {
Kojto 71:53949e6131f6 135 s_ep_buf_ind = 8;
Kojto 71:53949e6131f6 136 }
Kojto 71:53949e6131f6 137
Kojto 71:53949e6131f6 138 void USBHAL::setAddress(uint8_t address)
Kojto 71:53949e6131f6 139 {
Kojto 71:53949e6131f6 140 // NOTE: Delay address setting; otherwise, USB controller won't ack.
Kojto 71:53949e6131f6 141 s_usb_addr = address;
Kojto 71:53949e6131f6 142 }
Kojto 71:53949e6131f6 143
Kojto 71:53949e6131f6 144 void USBHAL::remoteWakeup(void)
Kojto 71:53949e6131f6 145 {
Kojto 71:53949e6131f6 146 #if 0
Kojto 71:53949e6131f6 147 USBD->OPER |= USBD_OPER_RESUMEEN_Msk;
Kojto 71:53949e6131f6 148 #endif
Kojto 71:53949e6131f6 149 }
Kojto 71:53949e6131f6 150
Kojto 71:53949e6131f6 151 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
Kojto 71:53949e6131f6 152 {
Kojto 71:53949e6131f6 153 uint32_t ep_type = 0;
Kojto 71:53949e6131f6 154 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Kojto 71:53949e6131f6 155 uint32_t ep_logic_index = NU_EP2EPL(endpoint);
Kojto 71:53949e6131f6 156 uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT;
Kojto 71:53949e6131f6 157
Kojto 71:53949e6131f6 158 if (ep_logic_index == 3 || ep_logic_index == 4)
Kojto 71:53949e6131f6 159 ep_type = USBD_CFG_TYPE_ISO;
Kojto 71:53949e6131f6 160
Kojto 71:53949e6131f6 161 USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index);
Kojto 71:53949e6131f6 162 /* Buffer range */
Kojto 71:53949e6131f6 163 USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind);
Kojto 71:53949e6131f6 164
Kojto 71:53949e6131f6 165 if (ep_dir == USBD_CFG_EPMODE_OUT)
Kojto 71:53949e6131f6 166 USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket);
Kojto 71:53949e6131f6 167
Kojto 71:53949e6131f6 168 s_ep_mxp[ep_logic_index] = maxPacket;
Kojto 71:53949e6131f6 169
Kojto 71:53949e6131f6 170 s_ep_buf_ind += maxPacket;
Kojto 71:53949e6131f6 171
Kojto 71:53949e6131f6 172 return true;
Kojto 71:53949e6131f6 173 }
Kojto 71:53949e6131f6 174
Kojto 71:53949e6131f6 175 void USBHAL::EP0setup(uint8_t *buffer)
Kojto 71:53949e6131f6 176 {
Kojto 71:53949e6131f6 177 uint32_t sz;
Kojto 71:53949e6131f6 178 endpointReadResult(EP0OUT, buffer, &sz);
Kojto 71:53949e6131f6 179 }
Kojto 71:53949e6131f6 180
Kojto 71:53949e6131f6 181 void USBHAL::EP0read(void)
Kojto 71:53949e6131f6 182 {
Kojto 71:53949e6131f6 183
Kojto 71:53949e6131f6 184
Kojto 71:53949e6131f6 185 }
Kojto 71:53949e6131f6 186
Kojto 71:53949e6131f6 187 void USBHAL::EP0readStage(void)
Kojto 71:53949e6131f6 188 {
Kojto 71:53949e6131f6 189 // N/A
Kojto 71:53949e6131f6 190
Kojto 71:53949e6131f6 191 USBD_PrepareCtrlOut(0,0);
Kojto 71:53949e6131f6 192 }
Kojto 71:53949e6131f6 193
Kojto 71:53949e6131f6 194 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
Kojto 71:53949e6131f6 195 {
Kojto 71:53949e6131f6 196 uint32_t i;
Kojto 71:53949e6131f6 197 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1));
Kojto 71:53949e6131f6 198 uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1);
Kojto 71:53949e6131f6 199 for (i = 0; i < ceprxcnt; i ++)
Kojto 71:53949e6131f6 200 buffer[i] = buf[i];
Kojto 71:53949e6131f6 201 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
Kojto 71:53949e6131f6 202 return ceprxcnt;
Kojto 71:53949e6131f6 203 }
Kojto 71:53949e6131f6 204
Kojto 71:53949e6131f6 205 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
Kojto 71:53949e6131f6 206 {
Kojto 71:53949e6131f6 207 if (buffer && size)
Kojto 71:53949e6131f6 208 {
Kojto 71:53949e6131f6 209 if (s_ep_data_bit[0] & 1)
Kojto 71:53949e6131f6 210 USBD_SET_DATA1(EP0);
Kojto 71:53949e6131f6 211 else
Kojto 71:53949e6131f6 212 USBD_SET_DATA0(EP0);
Kojto 71:53949e6131f6 213 s_ep_data_bit[0]++;
Kojto 71:53949e6131f6 214
Kojto 71:53949e6131f6 215 USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size);
Kojto 71:53949e6131f6 216 USBD_SET_PAYLOAD_LEN(EP0, size);
Kojto 71:53949e6131f6 217 if (size < MAX_PACKET_SIZE_EP0)
Kojto 71:53949e6131f6 218 s_ep_data_bit[0] = 1;
Kojto 71:53949e6131f6 219
Kojto 71:53949e6131f6 220 }
Kojto 71:53949e6131f6 221 else
Kojto 71:53949e6131f6 222 {
Kojto 71:53949e6131f6 223 if (g_usbd_SetupPacket[0] & 0x80) //Device to Host
Kojto 71:53949e6131f6 224 {
Kojto 71:53949e6131f6 225 // Status stage
Kojto 71:53949e6131f6 226 // USBD_PrepareCtrlOut(0,0);
Kojto 71:53949e6131f6 227 } else
Kojto 71:53949e6131f6 228 {
Kojto 71:53949e6131f6 229 USBD_SET_DATA1(EP0);
Kojto 71:53949e6131f6 230 USBD_SET_PAYLOAD_LEN(EP0, 0);
Kojto 71:53949e6131f6 231 }
Kojto 71:53949e6131f6 232 }
Kojto 71:53949e6131f6 233 }
Kojto 71:53949e6131f6 234
Kojto 71:53949e6131f6 235 void USBHAL::EP0getWriteResult(void)
Kojto 71:53949e6131f6 236 {
Kojto 71:53949e6131f6 237 // N/A
Kojto 71:53949e6131f6 238 }
Kojto 71:53949e6131f6 239
Kojto 71:53949e6131f6 240 void USBHAL::EP0stall(void)
Kojto 71:53949e6131f6 241 {
Kojto 71:53949e6131f6 242 stallEndpoint(EP0OUT);
Kojto 71:53949e6131f6 243 }
Kojto 71:53949e6131f6 244
Kojto 71:53949e6131f6 245 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
Kojto 71:53949e6131f6 246 {
Kojto 71:53949e6131f6 247 return EP_PENDING;
Kojto 71:53949e6131f6 248 }
Kojto 71:53949e6131f6 249
Kojto 71:53949e6131f6 250 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng
Kojto 71:53949e6131f6 251 {
Kojto 71:53949e6131f6 252 if (endpoint == EP0OUT)
Kojto 71:53949e6131f6 253 {
Kojto 71:53949e6131f6 254 USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
Kojto 71:53949e6131f6 255 if (buffer) {
Kojto 71:53949e6131f6 256 USBD_MemCopy(buffer, g_usbd_SetupPacket, 8);
Kojto 71:53949e6131f6 257 }
Kojto 71:53949e6131f6 258 USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0);
Kojto 71:53949e6131f6 259 }
Kojto 71:53949e6131f6 260 else
Kojto 71:53949e6131f6 261 {
Kojto 71:53949e6131f6 262 uint32_t i;
Kojto 71:53949e6131f6 263 uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint)));
Kojto 71:53949e6131f6 264 uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint));
Kojto 71:53949e6131f6 265 for (i = 0; i < eprxcnt; i ++)
Kojto 71:53949e6131f6 266 buffer[i] = buf[i];
Kojto 71:53949e6131f6 267
Kojto 71:53949e6131f6 268 *bytesRead = eprxcnt;
Kojto 71:53949e6131f6 269
Kojto 71:53949e6131f6 270 USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]);
Kojto 71:53949e6131f6 271 }
Kojto 71:53949e6131f6 272 return EP_COMPLETED;
Kojto 71:53949e6131f6 273 }
Kojto 71:53949e6131f6 274
Kojto 71:53949e6131f6 275
Kojto 71:53949e6131f6 276 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer)
Kojto 71:53949e6131f6 277 {
Kojto 71:53949e6131f6 278 return 0;
Kojto 71:53949e6131f6 279 }
Kojto 71:53949e6131f6 280
Kojto 71:53949e6131f6 281 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
Kojto 71:53949e6131f6 282 {
Kojto 71:53949e6131f6 283 uint32_t ep_logic_index = NU_EP2EPL(endpoint);
Kojto 71:53949e6131f6 284 if (ep_logic_index == 0)
Kojto 71:53949e6131f6 285 return EP_INVALID;
Kojto 71:53949e6131f6 286 else
Kojto 71:53949e6131f6 287 {
Kojto 71:53949e6131f6 288 uint8_t *buf;
Kojto 71:53949e6131f6 289 uint32_t i=0;
Kojto 71:53949e6131f6 290 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Kojto 71:53949e6131f6 291 s_ep_compl |= (1 << ep_logic_index);
Kojto 71:53949e6131f6 292 buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index));
Kojto 71:53949e6131f6 293 for (i=0;i<size;i++)
Kojto 71:53949e6131f6 294 buf[i] = data[i];
Kojto 71:53949e6131f6 295
Kojto 71:53949e6131f6 296 /* Set transfer length and trigger IN transfer */
Kojto 71:53949e6131f6 297 USBD_SET_PAYLOAD_LEN(ep_hw_index, size);
Kojto 71:53949e6131f6 298
Kojto 71:53949e6131f6 299 }
Kojto 71:53949e6131f6 300 return EP_PENDING;
Kojto 71:53949e6131f6 301 }
Kojto 71:53949e6131f6 302
Kojto 71:53949e6131f6 303 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
Kojto 71:53949e6131f6 304 {
Kojto 71:53949e6131f6 305 if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint))))
Kojto 71:53949e6131f6 306 return EP_COMPLETED;
Kojto 71:53949e6131f6 307 return EP_PENDING;
Kojto 71:53949e6131f6 308 }
Kojto 71:53949e6131f6 309
Kojto 71:53949e6131f6 310 void USBHAL::stallEndpoint(uint8_t endpoint)
Kojto 71:53949e6131f6 311 {
Kojto 71:53949e6131f6 312 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Kojto 71:53949e6131f6 313 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Kojto 71:53949e6131f6 314 return;
Kojto 71:53949e6131f6 315
Kojto 71:53949e6131f6 316 USBD_SetStall(NU_EPH2EPL(ep_hw_index));
Kojto 71:53949e6131f6 317
Kojto 71:53949e6131f6 318 }
Kojto 71:53949e6131f6 319
Kojto 71:53949e6131f6 320 void USBHAL::unstallEndpoint(uint8_t endpoint)
Kojto 71:53949e6131f6 321 {
Kojto 71:53949e6131f6 322 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Kojto 71:53949e6131f6 323 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Kojto 71:53949e6131f6 324 return;
Kojto 71:53949e6131f6 325 USBD_ClearStall(NU_EPH2EPL(ep_hw_index));
Kojto 71:53949e6131f6 326 }
Kojto 71:53949e6131f6 327
Kojto 71:53949e6131f6 328 bool USBHAL::getEndpointStallState(uint8_t endpoint)
Kojto 71:53949e6131f6 329 {
Kojto 71:53949e6131f6 330 uint32_t ep_hw_index = NU_EP2EPH(endpoint);
Kojto 71:53949e6131f6 331 if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS)
Kojto 71:53949e6131f6 332 return false;
Kojto 71:53949e6131f6 333
Kojto 71:53949e6131f6 334 return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0;
Kojto 71:53949e6131f6 335 }
Kojto 71:53949e6131f6 336
Kojto 71:53949e6131f6 337 void USBHAL::_usbisr(void)
Kojto 71:53949e6131f6 338 {
Kojto 71:53949e6131f6 339 MBED_ASSERT(instance);
Kojto 71:53949e6131f6 340 instance->usbisr();
Kojto 71:53949e6131f6 341 }
Kojto 71:53949e6131f6 342
Kojto 71:53949e6131f6 343 void USBHAL::usbisr(void)
Kojto 71:53949e6131f6 344 {
Kojto 71:53949e6131f6 345 uint32_t u32IntSts = USBD_GET_INT_FLAG();
Kojto 71:53949e6131f6 346 uint32_t u32State = USBD_GET_BUS_STATE();
Kojto 71:53949e6131f6 347
Kojto 71:53949e6131f6 348 //------------------------------------------------------------------
Kojto 71:53949e6131f6 349 if (u32IntSts & USBD_INTSTS_VBDETIF_Msk)
Kojto 71:53949e6131f6 350 {
Kojto 71:53949e6131f6 351 // Floating detect
Kojto 71:53949e6131f6 352 USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk);
Kojto 71:53949e6131f6 353
Kojto 71:53949e6131f6 354 if (USBD_IS_ATTACHED())
Kojto 71:53949e6131f6 355 {
Kojto 71:53949e6131f6 356 /* USB Plug In */
Kojto 71:53949e6131f6 357 USBD_ENABLE_USB();
Kojto 71:53949e6131f6 358 }
Kojto 71:53949e6131f6 359 else
Kojto 71:53949e6131f6 360 {
Kojto 71:53949e6131f6 361 /* USB Un-plug */
Kojto 71:53949e6131f6 362 USBD_DISABLE_USB();
Kojto 71:53949e6131f6 363 }
Kojto 71:53949e6131f6 364 }
Kojto 71:53949e6131f6 365
Kojto 71:53949e6131f6 366 //------------------------------------------------------------------
Kojto 71:53949e6131f6 367 if (u32IntSts & USBD_INTSTS_BUSIF_Msk)
Kojto 71:53949e6131f6 368 {
Kojto 71:53949e6131f6 369 /* Clear event flag */
Kojto 71:53949e6131f6 370 USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk);
Kojto 71:53949e6131f6 371
Kojto 71:53949e6131f6 372 if (u32State & USBD_ATTR_USBRST_Msk)
Kojto 71:53949e6131f6 373 {
Kojto 71:53949e6131f6 374 /* Bus reset */
Kojto 71:53949e6131f6 375 USBD_ENABLE_USB();
Kojto 71:53949e6131f6 376 USBD_SwReset();
Kojto 71:53949e6131f6 377 }
Kojto 71:53949e6131f6 378 if (u32State & USBD_ATTR_SUSPEND_Msk)
Kojto 71:53949e6131f6 379 {
Kojto 71:53949e6131f6 380 /* Enable USB but disable PHY */
Kojto 71:53949e6131f6 381 USBD_DISABLE_PHY();
Kojto 71:53949e6131f6 382 }
Kojto 71:53949e6131f6 383 if (u32State & USBD_ATTR_RESUME_Msk)
Kojto 71:53949e6131f6 384 {
Kojto 71:53949e6131f6 385 /* Enable USB and enable PHY */
Kojto 71:53949e6131f6 386 USBD_ENABLE_USB();
Kojto 71:53949e6131f6 387 }
Kojto 71:53949e6131f6 388 }
Kojto 71:53949e6131f6 389
Kojto 71:53949e6131f6 390 if (u32IntSts & USBD_INTSTS_USBIF_Msk)
Kojto 71:53949e6131f6 391 {
Kojto 71:53949e6131f6 392 // USB event
Kojto 71:53949e6131f6 393 if (u32IntSts & USBD_INTSTS_SETUP_Msk)
Kojto 71:53949e6131f6 394 {
Kojto 71:53949e6131f6 395 // Setup packet
Kojto 71:53949e6131f6 396 /* Clear event flag */
Kojto 71:53949e6131f6 397 USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk);
Kojto 71:53949e6131f6 398
Kojto 71:53949e6131f6 399 /* Clear the data IN/OUT ready flag of control end-points */
Kojto 71:53949e6131f6 400 USBD_STOP_TRANSACTION(EP0);
Kojto 71:53949e6131f6 401 USBD_STOP_TRANSACTION(EP1);
Kojto 71:53949e6131f6 402 EP0setupCallback();
Kojto 71:53949e6131f6 403 }
Kojto 71:53949e6131f6 404
Kojto 71:53949e6131f6 405 // EP events
Kojto 71:53949e6131f6 406 if (u32IntSts & USBD_INTSTS_EP0)
Kojto 71:53949e6131f6 407 {
Kojto 71:53949e6131f6 408 /* Clear event flag */
Kojto 71:53949e6131f6 409 USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
Kojto 71:53949e6131f6 410 // control IN
Kojto 71:53949e6131f6 411 EP0in();
Kojto 71:53949e6131f6 412
Kojto 71:53949e6131f6 413 // In ACK for Set address
Kojto 71:53949e6131f6 414 if ((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS))
Kojto 71:53949e6131f6 415 {
Kojto 71:53949e6131f6 416 if ((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0))
Kojto 71:53949e6131f6 417 {
Kojto 71:53949e6131f6 418 USBD_SET_ADDR(s_usb_addr);
Kojto 71:53949e6131f6 419 }
Kojto 71:53949e6131f6 420 }
Kojto 71:53949e6131f6 421 }
Kojto 71:53949e6131f6 422 if (u32IntSts & USBD_INTSTS_EP1)
Kojto 71:53949e6131f6 423 {
Kojto 71:53949e6131f6 424 /* Clear event flag */
Kojto 71:53949e6131f6 425 USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
Kojto 71:53949e6131f6 426
Kojto 71:53949e6131f6 427 // control OUT
Kojto 71:53949e6131f6 428 EP0out();
Kojto 71:53949e6131f6 429 }
Kojto 71:53949e6131f6 430
Kojto 71:53949e6131f6 431 uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F;
Kojto 71:53949e6131f6 432 uint32_t ep_hw_index = 2;
Kojto 71:53949e6131f6 433 while (gintsts_epx) {
Kojto 71:53949e6131f6 434 if (gintsts_epx & 0x01)
Kojto 71:53949e6131f6 435 {
Kojto 71:53949e6131f6 436 uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7;
Kojto 71:53949e6131f6 437 /* Clear event flag */
Kojto 71:53949e6131f6 438 USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16));
Kojto 71:53949e6131f6 439
Kojto 71:53949e6131f6 440 if (ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3)) //RX
Kojto 71:53949e6131f6 441 {
Kojto 71:53949e6131f6 442 if (ep_status == 0x07)
Kojto 71:53949e6131f6 443 SOF(frame_cnt++);
Kojto 71:53949e6131f6 444 if ((instance->*(epCallback[ep_hw_index-2]))())
Kojto 71:53949e6131f6 445 {
Kojto 71:53949e6131f6 446
Kojto 71:53949e6131f6 447 }
Kojto 71:53949e6131f6 448 USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]);
Kojto 71:53949e6131f6 449 }
Kojto 71:53949e6131f6 450 else if (ep_status == 0x00 || ep_status == 0x07) //TX
Kojto 71:53949e6131f6 451 {
Kojto 71:53949e6131f6 452 s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index)));
Kojto 71:53949e6131f6 453 if ((instance->*(epCallback[ep_hw_index-2]))())
Kojto 71:53949e6131f6 454 {
Kojto 71:53949e6131f6 455 }
Kojto 71:53949e6131f6 456 }
Kojto 71:53949e6131f6 457 }
Kojto 71:53949e6131f6 458
Kojto 71:53949e6131f6 459 gintsts_epx = gintsts_epx >> 1;
Kojto 71:53949e6131f6 460 ep_hw_index++;
Kojto 71:53949e6131f6 461 }
Kojto 71:53949e6131f6 462 }
Kojto 71:53949e6131f6 463 }
Kojto 71:53949e6131f6 464 #endif
Kojto 71:53949e6131f6 465