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