USBDevice with MAX32620HSP platform support

Fork of USBDevice by mbed official

Committer:
mbed_official
Date:
Thu Aug 13 15:46:06 2015 +0100
Revision:
59:2af474687369
Synchronized with git revision 376d6a73e345b728a788041adb166b08cd8d2b95

Full URL: https://github.com/mbedmicro/mbed/commit/376d6a73e345b728a788041adb166b08cd8d2b95/

Silicon Labs - Add support for USBDevice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 59:2af474687369 1 /* Copyright 2015 Silicon Labs, http://www.silabs.com
mbed_official 59:2af474687369 2 *
mbed_official 59:2af474687369 3 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 59:2af474687369 4 * you may not use this file except in compliance with the License.
mbed_official 59:2af474687369 5 * You may obtain a copy of the License at
mbed_official 59:2af474687369 6 *
mbed_official 59:2af474687369 7 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 59:2af474687369 8 *
mbed_official 59:2af474687369 9 * Unless required by applicable law or agreed to in writing, software
mbed_official 59:2af474687369 10 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 59:2af474687369 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 59:2af474687369 12 * See the License for the specific language governing permissions and
mbed_official 59:2af474687369 13 * limitations under the License.
mbed_official 59:2af474687369 14 */
mbed_official 59:2af474687369 15
mbed_official 59:2af474687369 16 #if defined TARGET_EFM32GG_STK3700 || \
mbed_official 59:2af474687369 17 defined TARGET_EFM32LG_STK3600 || \
mbed_official 59:2af474687369 18 defined TARGET_EFM32WG_STK3800 || \
mbed_official 59:2af474687369 19 defined TARGET_EFM32HG_STK3400
mbed_official 59:2af474687369 20
mbed_official 59:2af474687369 21 #include "USBHAL.h"
mbed_official 59:2af474687369 22 #include "em_usb.h"
mbed_official 59:2af474687369 23 #include "em_usbtypes.h"
mbed_official 59:2af474687369 24 #include "em_usbhal.h"
mbed_official 59:2af474687369 25 #include "em_usbd.h"
mbed_official 59:2af474687369 26
mbed_official 59:2af474687369 27 #include "sleepmodes.h"
mbed_official 59:2af474687369 28
mbed_official 59:2af474687369 29 enum USBISRCommand {
mbed_official 59:2af474687369 30 CMD_HANDLED = 0,
mbed_official 59:2af474687369 31 CMD_EP0SETUP,
mbed_official 59:2af474687369 32 CMD_EP0IN,
mbed_official 59:2af474687369 33 CMD_EP0OUT,
mbed_official 59:2af474687369 34 CMD_EP_XFER_COMPLETED,
mbed_official 59:2af474687369 35 CMD_SOF,
mbed_official 59:2af474687369 36 CMD_BUSRESET,
mbed_official 59:2af474687369 37 CMD_SUSPEND_STATE_CHANGED,
mbed_official 59:2af474687369 38 CMD_ENUM_END_MARKER
mbed_official 59:2af474687369 39 };
mbed_official 59:2af474687369 40
mbed_official 59:2af474687369 41 enum IEPStatus {
mbed_official 59:2af474687369 42 NOT_CONFIGURED = 0,
mbed_official 59:2af474687369 43 IDLE = 1,
mbed_official 59:2af474687369 44 READ_PENDING = 2,
mbed_official 59:2af474687369 45 WRITE_PENDING = 3,
mbed_official 59:2af474687369 46 READ_COMPLETE = 4,
mbed_official 59:2af474687369 47 WRITE_COMPLETE = 5,
mbed_official 59:2af474687369 48 FAILED_INVALID = 6,
mbed_official 59:2af474687369 49 FAILED_STALLED = 7
mbed_official 59:2af474687369 50 };
mbed_official 59:2af474687369 51
mbed_official 59:2af474687369 52 typedef struct {
mbed_official 59:2af474687369 53 IEPStatus status;
mbed_official 59:2af474687369 54 uint32_t byte_count;
mbed_official 59:2af474687369 55 uint32_t max_packet;
mbed_official 59:2af474687369 56 USB_XferCompleteCb_TypeDef intern_cb;
mbed_official 59:2af474687369 57 uint8_t *data_buf;
mbed_official 59:2af474687369 58 } ep_state_t;
mbed_official 59:2af474687369 59
mbed_official 59:2af474687369 60 USBHAL * USBHAL::instance;
mbed_official 59:2af474687369 61 static uint8_t ep0setupdata[8];
mbed_official 59:2af474687369 62 static ep_state_t ep_state[NUMBER_OF_ENDPOINTS];
mbed_official 59:2af474687369 63 #ifdef USB_USE_DYNAMIC_MEMORY
mbed_official 59:2af474687369 64 static uint8_t ep0in_data_buf[MAX_PACKET_SIZE_EP0] __attribute__ ((aligned (4)));
mbed_official 59:2af474687369 65 static uint8_t ep0out_data_buf[MAX_PACKET_SIZE_EP0]; // FIXME: does this need to be this big?
mbed_official 59:2af474687369 66 #else
mbed_official 59:2af474687369 67 static uint8_t ep_data_buf[NUMBER_OF_ENDPOINTS][64] __attribute__ ((aligned (4)));
mbed_official 59:2af474687369 68 #endif
mbed_official 59:2af474687369 69
mbed_official 59:2af474687369 70 static void run_cmd(USBISRCommand cmd, uint32_t param);
mbed_official 59:2af474687369 71 static void (*isrptr)() = NULL;
mbed_official 59:2af474687369 72 static USBISRCommand usb_isrcmd = CMD_HANDLED;
mbed_official 59:2af474687369 73 static uint32_t usb_isrcmd_param = 0;
mbed_official 59:2af474687369 74
mbed_official 59:2af474687369 75 extern "C" void usbhal_allow_em2(bool allow_em2);
mbed_official 59:2af474687369 76
mbed_official 59:2af474687369 77 #ifdef DEBUG_USB_API
mbed_official 59:2af474687369 78 #define TRACE(fmt,...) printf("USB: %s: " fmt "\n", __func__, __VA_ARGS__);
mbed_official 59:2af474687369 79 #define TRACE_FUNC_IN printf("USB: > %s\n",__func__);
mbed_official 59:2af474687369 80 #define TRACE_FUNC_IN_P(fmt, ...) printf("USB: > %s: " fmt "\n", __func__, __VA_ARGS__);
mbed_official 59:2af474687369 81 #else
mbed_official 59:2af474687369 82 #define TRACE(fmt,...)
mbed_official 59:2af474687369 83 #define TRACE_FUNC_IN
mbed_official 59:2af474687369 84 #define TRACE_FUNC_IN_P(fmt, ...)
mbed_official 59:2af474687369 85 #endif
mbed_official 59:2af474687369 86
mbed_official 59:2af474687369 87 static EP_STATUS internEndpointRead(uint8_t ep, uint32_t maxSize);
mbed_official 59:2af474687369 88
mbed_official 59:2af474687369 89 static int usbhal_xfer_complete_cb(uint8_t epaddr, USB_Status_TypeDef status,
mbed_official 59:2af474687369 90 uint32_t xferred, uint32_t remaining);
mbed_official 59:2af474687369 91 static void usbhal_free_buffers(void);
mbed_official 59:2af474687369 92
mbed_official 59:2af474687369 93 /* Internal EP transfer complete callbacks */
mbed_official 59:2af474687369 94 #define EPCB(n) static int usbhal_xfer_complete_cb_##n(USB_Status_TypeDef status, \
mbed_official 59:2af474687369 95 uint32_t xferred, uint32_t remaining) { \
mbed_official 59:2af474687369 96 return usbhal_xfer_complete_cb(n, status, xferred, remaining); \
mbed_official 59:2af474687369 97 }
mbed_official 59:2af474687369 98 /* ------^ */
mbed_official 59:2af474687369 99 EPCB(EP0OUT)
mbed_official 59:2af474687369 100 EPCB(EP0IN)
mbed_official 59:2af474687369 101 EPCB(EP1OUT)
mbed_official 59:2af474687369 102 EPCB(EP1IN)
mbed_official 59:2af474687369 103 EPCB(EP2OUT)
mbed_official 59:2af474687369 104 EPCB(EP2IN)
mbed_official 59:2af474687369 105 EPCB(EP3OUT)
mbed_official 59:2af474687369 106 EPCB(EP3IN)
mbed_official 59:2af474687369 107 #ifndef TARGET_EFM32HG_STK3400
mbed_official 59:2af474687369 108 EPCB(EP4OUT)
mbed_official 59:2af474687369 109 EPCB(EP4IN)
mbed_official 59:2af474687369 110 EPCB(EP5OUT)
mbed_official 59:2af474687369 111 EPCB(EP5IN)
mbed_official 59:2af474687369 112 EPCB(EP6OUT)
mbed_official 59:2af474687369 113 EPCB(EP6IN)
mbed_official 59:2af474687369 114 #endif
mbed_official 59:2af474687369 115
mbed_official 59:2af474687369 116 static inline bool is_aligned(const void *pointer, size_t byte_count)
mbed_official 59:2af474687369 117 {
mbed_official 59:2af474687369 118 return ((uintptr_t)pointer % byte_count == 0);
mbed_official 59:2af474687369 119 }
mbed_official 59:2af474687369 120
mbed_official 59:2af474687369 121 USBHAL::USBHAL(void)
mbed_official 59:2af474687369 122 {
mbed_official 59:2af474687369 123 TRACE_FUNC_IN;
mbed_official 59:2af474687369 124
mbed_official 59:2af474687369 125 isrptr = &USBHAL::_usbisr;
mbed_official 59:2af474687369 126
mbed_official 59:2af474687369 127 if (instance) {
mbed_official 59:2af474687369 128 TRACE("Assert self failed! instance=%p", instance);
mbed_official 59:2af474687369 129 abort();
mbed_official 59:2af474687369 130 }
mbed_official 59:2af474687369 131 instance = this;
mbed_official 59:2af474687369 132
mbed_official 59:2af474687369 133 // When USB is active, we can't go below EM1. This block may
mbed_official 59:2af474687369 134 // be dynamically removed/reinstated to allow deeper sleep.
mbed_official 59:2af474687369 135 usbhal_allow_em2(false);
mbed_official 59:2af474687369 136
mbed_official 59:2af474687369 137 // When in suspend / Vbus off we can go to EM2, but never below
mbed_official 59:2af474687369 138 // that as long as USB is being used. Despite the name the call here
mbed_official 59:2af474687369 139 // blocks entering modes _below_ EM2, but allows EM2.
mbed_official 59:2af474687369 140 blockSleepMode(EM2);
mbed_official 59:2af474687369 141
mbed_official 59:2af474687369 142 epCallback[EP0OUT] = NULL;
mbed_official 59:2af474687369 143 epCallback[EP0IN ] = NULL;
mbed_official 59:2af474687369 144 epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
mbed_official 59:2af474687369 145 epCallback[EP1IN ] = &USBHAL::EP1_IN_callback;
mbed_official 59:2af474687369 146 epCallback[EP2OUT] = &USBHAL::EP2_OUT_callback;
mbed_official 59:2af474687369 147 epCallback[EP2IN ] = &USBHAL::EP2_IN_callback;
mbed_official 59:2af474687369 148 epCallback[EP3OUT] = &USBHAL::EP3_OUT_callback;
mbed_official 59:2af474687369 149 epCallback[EP3IN ] = &USBHAL::EP3_IN_callback;
mbed_official 59:2af474687369 150 #ifndef TARGET_EFM32HG_STK3400
mbed_official 59:2af474687369 151 epCallback[EP4OUT] = &USBHAL::EP4_OUT_callback;
mbed_official 59:2af474687369 152 epCallback[EP4IN ] = &USBHAL::EP4_IN_callback;
mbed_official 59:2af474687369 153 epCallback[EP5OUT] = &USBHAL::EP5_OUT_callback;
mbed_official 59:2af474687369 154 epCallback[EP5IN ] = &USBHAL::EP5_IN_callback;
mbed_official 59:2af474687369 155 epCallback[EP6OUT] = &USBHAL::EP6_OUT_callback;
mbed_official 59:2af474687369 156 epCallback[EP6IN ] = &USBHAL::EP6_IN_callback;
mbed_official 59:2af474687369 157 #endif
mbed_official 59:2af474687369 158
mbed_official 59:2af474687369 159 memset(ep_state, 0, sizeof(ep_state));
mbed_official 59:2af474687369 160
mbed_official 59:2af474687369 161 ep_state[EP0OUT].intern_cb = usbhal_xfer_complete_cb_EP0OUT;
mbed_official 59:2af474687369 162 ep_state[EP0IN ].intern_cb = usbhal_xfer_complete_cb_EP0IN;
mbed_official 59:2af474687369 163 ep_state[EP1OUT].intern_cb = usbhal_xfer_complete_cb_EP1OUT;
mbed_official 59:2af474687369 164 ep_state[EP1IN ].intern_cb = usbhal_xfer_complete_cb_EP1IN;
mbed_official 59:2af474687369 165 ep_state[EP2OUT].intern_cb = usbhal_xfer_complete_cb_EP2OUT;
mbed_official 59:2af474687369 166 ep_state[EP2IN ].intern_cb = usbhal_xfer_complete_cb_EP2IN;
mbed_official 59:2af474687369 167 ep_state[EP3OUT].intern_cb = usbhal_xfer_complete_cb_EP3OUT;
mbed_official 59:2af474687369 168 ep_state[EP3IN ].intern_cb = usbhal_xfer_complete_cb_EP3IN;
mbed_official 59:2af474687369 169 #ifndef TARGET_EFM32HG_STK3400
mbed_official 59:2af474687369 170 ep_state[EP4OUT].intern_cb = usbhal_xfer_complete_cb_EP4OUT;
mbed_official 59:2af474687369 171 ep_state[EP4IN ].intern_cb = usbhal_xfer_complete_cb_EP4IN;
mbed_official 59:2af474687369 172 ep_state[EP5OUT].intern_cb = usbhal_xfer_complete_cb_EP5OUT;
mbed_official 59:2af474687369 173 ep_state[EP5IN ].intern_cb = usbhal_xfer_complete_cb_EP5IN;
mbed_official 59:2af474687369 174 ep_state[EP6OUT].intern_cb = usbhal_xfer_complete_cb_EP6OUT;
mbed_official 59:2af474687369 175 ep_state[EP6IN ].intern_cb = usbhal_xfer_complete_cb_EP6IN;
mbed_official 59:2af474687369 176 #endif
mbed_official 59:2af474687369 177
mbed_official 59:2af474687369 178 #ifdef USB_USE_DYNAMIC_MEMORY
mbed_official 59:2af474687369 179 ep_state[EP0OUT].data_buf = ep0out_data_buf;
mbed_official 59:2af474687369 180 ep_state[EP0IN].data_buf = ep0in_data_buf;
mbed_official 59:2af474687369 181 #else
mbed_official 59:2af474687369 182 for (int i=0 ; i<NUMBER_OF_ENDPOINTS ; i++) {
mbed_official 59:2af474687369 183 ep_state[i].data_buf = ep_data_buf[i];
mbed_official 59:2af474687369 184 }
mbed_official 59:2af474687369 185 #endif
mbed_official 59:2af474687369 186 }
mbed_official 59:2af474687369 187
mbed_official 59:2af474687369 188 USBHAL::~USBHAL(void)
mbed_official 59:2af474687369 189 {
mbed_official 59:2af474687369 190 TRACE_FUNC_IN;
mbed_official 59:2af474687369 191 USBD_AbortAllTransfers();
mbed_official 59:2af474687369 192 USBD_Disconnect();
mbed_official 59:2af474687369 193 usbhal_free_buffers();
mbed_official 59:2af474687369 194
mbed_official 59:2af474687369 195 usbhal_allow_em2(true);
mbed_official 59:2af474687369 196 unblockSleepMode(EM2);
mbed_official 59:2af474687369 197 }
mbed_official 59:2af474687369 198
mbed_official 59:2af474687369 199 extern "C" void usbhal_allow_em2(bool allow_em2)
mbed_official 59:2af474687369 200 {
mbed_official 59:2af474687369 201 if (allow_em2) {
mbed_official 59:2af474687369 202 // unblockSleepMode is safe to call even if we would unblock
mbed_official 59:2af474687369 203 // an already unblocked mode, so no checks here.
mbed_official 59:2af474687369 204 unblockSleepMode(EM1);
mbed_official 59:2af474687369 205 } else {
mbed_official 59:2af474687369 206 blockSleepMode(EM1);
mbed_official 59:2af474687369 207 }
mbed_official 59:2af474687369 208 }
mbed_official 59:2af474687369 209
mbed_official 59:2af474687369 210 static void usbhal_reset_cb(void)
mbed_official 59:2af474687369 211 {
mbed_official 59:2af474687369 212 TRACE_FUNC_IN;
mbed_official 59:2af474687369 213 run_cmd(CMD_BUSRESET, 0);
mbed_official 59:2af474687369 214 }
mbed_official 59:2af474687369 215
mbed_official 59:2af474687369 216 #ifdef DEBUG_USB_API
mbed_official 59:2af474687369 217 static const char *usbstate[] = { "NONE", "ATTACHED", "POWERED", "DEFAULT",
mbed_official 59:2af474687369 218 "ADDRESSED", "CONFIGURED", "SUSPENDED", "???" };
mbed_official 59:2af474687369 219 #endif
mbed_official 59:2af474687369 220
mbed_official 59:2af474687369 221 static void usbhal_state_change_cb(USBD_State_TypeDef oldState,
mbed_official 59:2af474687369 222 USBD_State_TypeDef newState)
mbed_official 59:2af474687369 223 {
mbed_official 59:2af474687369 224 TRACE("state changed %s -> %s", usbstate[oldState], usbstate[newState]);
mbed_official 59:2af474687369 225
mbed_official 59:2af474687369 226 if (oldState == USBD_STATE_SUSPENDED) {
mbed_official 59:2af474687369 227 run_cmd(CMD_SUSPEND_STATE_CHANGED, 0);
mbed_official 59:2af474687369 228 }
mbed_official 59:2af474687369 229
mbed_official 59:2af474687369 230 if (newState == USBD_STATE_SUSPENDED) {
mbed_official 59:2af474687369 231 run_cmd(CMD_SUSPEND_STATE_CHANGED, 1);
mbed_official 59:2af474687369 232 }
mbed_official 59:2af474687369 233
mbed_official 59:2af474687369 234 // Should call connectStateChanged from here as well but there is
mbed_official 59:2af474687369 235 // no documentation on when to actually do so. (And the implementation
mbed_official 59:2af474687369 236 // in USBDevice.cpp is a stub)
mbed_official 59:2af474687369 237
mbed_official 59:2af474687369 238 // HACK! Since connectStateChanged is not used, indicate the loss
mbed_official 59:2af474687369 239 // off connection by reporting a bus reset. This causes USBDevice
mbed_official 59:2af474687369 240 // to realise that at least it's not in CONFIGURED anymore, and
mbed_official 59:2af474687369 241 // stop trying to read/write in a busyloop.
mbed_official 59:2af474687369 242 if (newState == USBD_STATE_NONE) {
mbed_official 59:2af474687369 243 run_cmd(CMD_BUSRESET, 0);
mbed_official 59:2af474687369 244 }
mbed_official 59:2af474687369 245 }
mbed_official 59:2af474687369 246
mbed_official 59:2af474687369 247 static int usbhal_setupcmd_cb(const USB_Setup_TypeDef *setup)
mbed_official 59:2af474687369 248 {
mbed_official 59:2af474687369 249 TRACE_FUNC_IN;
mbed_official 59:2af474687369 250 if (!setup) {
mbed_official 59:2af474687369 251 EFM_ASSERT(false);
mbed_official 59:2af474687369 252 return USB_STATUS_REQ_ERR;
mbed_official 59:2af474687369 253 }
mbed_official 59:2af474687369 254
mbed_official 59:2af474687369 255 memcpy(ep0setupdata, setup, 8);
mbed_official 59:2af474687369 256 run_cmd(CMD_EP0SETUP, 0);
mbed_official 59:2af474687369 257
mbed_official 59:2af474687369 258 return USB_STATUS_OK;
mbed_official 59:2af474687369 259 }
mbed_official 59:2af474687369 260
mbed_official 59:2af474687369 261 static void usbhal_sof_cb(uint16_t frameNum)
mbed_official 59:2af474687369 262 {
mbed_official 59:2af474687369 263 run_cmd(CMD_SOF, frameNum);
mbed_official 59:2af474687369 264 }
mbed_official 59:2af474687369 265
mbed_official 59:2af474687369 266 static void usbhal_free_buffers(void)
mbed_official 59:2af474687369 267 {
mbed_official 59:2af474687369 268 #ifdef USB_USE_DYNAMIC_MEMORY
mbed_official 59:2af474687369 269 TRACE_FUNC_IN;
mbed_official 59:2af474687369 270
mbed_official 59:2af474687369 271 for (int i=EP1OUT ; i<NUMBER_OF_ENDPOINTS ; i++ ) {
mbed_official 59:2af474687369 272 if (ep_state[i].data_buf) {
mbed_official 59:2af474687369 273 free(ep_state[i].data_buf);
mbed_official 59:2af474687369 274 ep_state[i].data_buf = NULL;
mbed_official 59:2af474687369 275 }
mbed_official 59:2af474687369 276 }
mbed_official 59:2af474687369 277 #endif
mbed_official 59:2af474687369 278 }
mbed_official 59:2af474687369 279
mbed_official 59:2af474687369 280 void USBHAL::connect(void)
mbed_official 59:2af474687369 281 {
mbed_official 59:2af474687369 282 TRACE_FUNC_IN;
mbed_official 59:2af474687369 283
mbed_official 59:2af474687369 284 // Init datastructures must be static - driver will use these even after the init function exits!
mbed_official 59:2af474687369 285
mbed_official 59:2af474687369 286 static const uint8_t buffer_multiplier[] = { 1 }; // Mult 1 for control EP
mbed_official 59:2af474687369 287 static const USBD_Callbacks_TypeDef usbd_callbacks = {
mbed_official 59:2af474687369 288 .usbReset = usbhal_reset_cb,
mbed_official 59:2af474687369 289 .usbStateChange = usbhal_state_change_cb,
mbed_official 59:2af474687369 290 .setupCmd = usbhal_setupcmd_cb,
mbed_official 59:2af474687369 291 .isSelfPowered = NULL,
mbed_official 59:2af474687369 292 .sofInt = usbhal_sof_cb
mbed_official 59:2af474687369 293 };
mbed_official 59:2af474687369 294
mbed_official 59:2af474687369 295 USBD_Init_TypeDef initdata = {
mbed_official 59:2af474687369 296 .deviceDescriptor = NULL,
mbed_official 59:2af474687369 297 .configDescriptor = NULL,
mbed_official 59:2af474687369 298 .stringDescriptors = NULL,
mbed_official 59:2af474687369 299 .numberOfStrings = 0,
mbed_official 59:2af474687369 300 .bufferingMultiplier = buffer_multiplier,
mbed_official 59:2af474687369 301 .callbacks = &usbd_callbacks,
mbed_official 59:2af474687369 302 .reserved = 0
mbed_official 59:2af474687369 303 };
mbed_official 59:2af474687369 304
mbed_official 59:2af474687369 305 int ret = USBD_Init(&initdata);
mbed_official 59:2af474687369 306
mbed_official 59:2af474687369 307 TRACE("init = %d, devicedesc = %lx, configdesc = %lx", ret,
mbed_official 59:2af474687369 308 (uint32_t) initdata.deviceDescriptor,
mbed_official 59:2af474687369 309 (uint32_t) initdata.configDescriptor);
mbed_official 59:2af474687369 310
mbed_official 59:2af474687369 311 EFM_ASSERT(ret == USB_STATUS_OK);
mbed_official 59:2af474687369 312 }
mbed_official 59:2af474687369 313
mbed_official 59:2af474687369 314 void USBHAL::disconnect(void)
mbed_official 59:2af474687369 315 {
mbed_official 59:2af474687369 316 TRACE_FUNC_IN;
mbed_official 59:2af474687369 317 USBD_Disconnect();
mbed_official 59:2af474687369 318 }
mbed_official 59:2af474687369 319
mbed_official 59:2af474687369 320 void USBHAL::configureDevice(void)
mbed_official 59:2af474687369 321 {
mbed_official 59:2af474687369 322 TRACE_FUNC_IN;
mbed_official 59:2af474687369 323 USBD_SetUsbState(USBD_STATE_CONFIGURED);
mbed_official 59:2af474687369 324 }
mbed_official 59:2af474687369 325
mbed_official 59:2af474687369 326 void USBHAL::unconfigureDevice(void)
mbed_official 59:2af474687369 327 {
mbed_official 59:2af474687369 328 TRACE_FUNC_IN;
mbed_official 59:2af474687369 329 USBD_SetUsbState(USBD_STATE_DEFAULT);
mbed_official 59:2af474687369 330 usbhal_free_buffers();
mbed_official 59:2af474687369 331 }
mbed_official 59:2af474687369 332
mbed_official 59:2af474687369 333 void USBHAL::setAddress(uint8_t address)
mbed_official 59:2af474687369 334 {
mbed_official 59:2af474687369 335 TRACE_FUNC_IN_P("addr 0x%x", (unsigned)address);
mbed_official 59:2af474687369 336 USBD_SetAddress(address);
mbed_official 59:2af474687369 337 }
mbed_official 59:2af474687369 338
mbed_official 59:2af474687369 339 void USBHAL::remoteWakeup(void)
mbed_official 59:2af474687369 340 {
mbed_official 59:2af474687369 341 TRACE_FUNC_IN;
mbed_official 59:2af474687369 342 USBD_RemoteWakeup();
mbed_official 59:2af474687369 343 }
mbed_official 59:2af474687369 344
mbed_official 59:2af474687369 345 void USBHAL::EP0setup(uint8_t *buffer)
mbed_official 59:2af474687369 346 {
mbed_official 59:2af474687369 347 TRACE_FUNC_IN;
mbed_official 59:2af474687369 348 EFM_ASSERT(buffer);
mbed_official 59:2af474687369 349 if (buffer) {
mbed_official 59:2af474687369 350 memcpy(buffer, ep0setupdata, 8);
mbed_official 59:2af474687369 351 }
mbed_official 59:2af474687369 352 }
mbed_official 59:2af474687369 353
mbed_official 59:2af474687369 354 void USBHAL::EP0read(void)
mbed_official 59:2af474687369 355 {
mbed_official 59:2af474687369 356 TRACE_FUNC_IN;
mbed_official 59:2af474687369 357 (void)internEndpointRead(0, MAX_PACKET_SIZE_EP0);
mbed_official 59:2af474687369 358 }
mbed_official 59:2af474687369 359
mbed_official 59:2af474687369 360 void USBHAL::EP0readStage(void)
mbed_official 59:2af474687369 361 {
mbed_official 59:2af474687369 362 TRACE_FUNC_IN;
mbed_official 59:2af474687369 363 // Not needed
mbed_official 59:2af474687369 364 }
mbed_official 59:2af474687369 365
mbed_official 59:2af474687369 366 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
mbed_official 59:2af474687369 367 {
mbed_official 59:2af474687369 368 TRACE_FUNC_IN;
mbed_official 59:2af474687369 369 EFM_ASSERT(buffer);
mbed_official 59:2af474687369 370
mbed_official 59:2af474687369 371 uint32_t read = 0;
mbed_official 59:2af474687369 372 endpointReadResult(0, buffer, &read);
mbed_official 59:2af474687369 373 return read;
mbed_official 59:2af474687369 374 }
mbed_official 59:2af474687369 375
mbed_official 59:2af474687369 376 static int usbhal_xfer_complete_cb(uint8_t ep, USB_Status_TypeDef status,
mbed_official 59:2af474687369 377 uint32_t xferred, uint32_t remaining)
mbed_official 59:2af474687369 378 {
mbed_official 59:2af474687369 379 TRACE_FUNC_IN_P("ep 0x%x, status %u, xferred %lu, rem %lu",
mbed_official 59:2af474687369 380 ep, status, xferred, remaining);
mbed_official 59:2af474687369 381
mbed_official 59:2af474687369 382 if (ep >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 383 EFM_ASSERT(false);
mbed_official 59:2af474687369 384 return USB_STATUS_REQ_ERR;
mbed_official 59:2af474687369 385 }
mbed_official 59:2af474687369 386
mbed_official 59:2af474687369 387 switch (ep) {
mbed_official 59:2af474687369 388 case EP0OUT:
mbed_official 59:2af474687369 389 if (ep_state[EP0OUT].status == READ_PENDING) {
mbed_official 59:2af474687369 390 ep_state[EP0OUT].status = READ_COMPLETE;
mbed_official 59:2af474687369 391 ep_state[EP0OUT].byte_count = xferred;
mbed_official 59:2af474687369 392 // drop zlp
mbed_official 59:2af474687369 393 if (xferred == 0) {
mbed_official 59:2af474687369 394 break;
mbed_official 59:2af474687369 395 }
mbed_official 59:2af474687369 396 }
mbed_official 59:2af474687369 397 run_cmd(CMD_EP0OUT, 0);
mbed_official 59:2af474687369 398 break;
mbed_official 59:2af474687369 399
mbed_official 59:2af474687369 400 case EP0IN:
mbed_official 59:2af474687369 401 run_cmd(CMD_EP0IN, 0);
mbed_official 59:2af474687369 402 break;
mbed_official 59:2af474687369 403
mbed_official 59:2af474687369 404 default:
mbed_official 59:2af474687369 405 bool write = ep & 1;
mbed_official 59:2af474687369 406
mbed_official 59:2af474687369 407 if (status == USB_STATUS_OK) {
mbed_official 59:2af474687369 408 if (!write && ep_state[ep].status == READ_PENDING) {
mbed_official 59:2af474687369 409 ep_state[ep].status = READ_COMPLETE;
mbed_official 59:2af474687369 410 ep_state[ep].byte_count = xferred;
mbed_official 59:2af474687369 411 } else if (write && ep_state[ep].status == WRITE_PENDING) {
mbed_official 59:2af474687369 412 ep_state[ep].status = WRITE_COMPLETE;
mbed_official 59:2af474687369 413 } else {
mbed_official 59:2af474687369 414 ep_state[ep].status = FAILED_INVALID;
mbed_official 59:2af474687369 415 }
mbed_official 59:2af474687369 416 } else {
mbed_official 59:2af474687369 417 ep_state[ep].status = FAILED_INVALID;
mbed_official 59:2af474687369 418 }
mbed_official 59:2af474687369 419
mbed_official 59:2af474687369 420 if (ep_state[ep].status != FAILED_INVALID) {
mbed_official 59:2af474687369 421 run_cmd(CMD_EP_XFER_COMPLETED, ep);
mbed_official 59:2af474687369 422 }
mbed_official 59:2af474687369 423 break;
mbed_official 59:2af474687369 424 }
mbed_official 59:2af474687369 425
mbed_official 59:2af474687369 426 return USB_STATUS_OK;
mbed_official 59:2af474687369 427 }
mbed_official 59:2af474687369 428
mbed_official 59:2af474687369 429 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
mbed_official 59:2af474687369 430 {
mbed_official 59:2af474687369 431 //TRACE_FUNC_IN_P("buffer %lx, size %lu", (uint32_t) buffer, size);
mbed_official 59:2af474687369 432
mbed_official 59:2af474687369 433 int ret;
mbed_official 59:2af474687369 434 USB_XferCompleteCb_TypeDef cb = ep_state[EP0IN].intern_cb;
mbed_official 59:2af474687369 435
mbed_official 59:2af474687369 436 EFM_ASSERT((buffer != NULL) || (size == 0));
mbed_official 59:2af474687369 437 EFM_ASSERT(size <= MAX_PACKET_SIZE_EP0);
mbed_official 59:2af474687369 438
mbed_official 59:2af474687369 439 if (!buffer || size == 0) {
mbed_official 59:2af474687369 440 // No callback after writing EP0 ZLP
mbed_official 59:2af474687369 441 cb = NULL;
mbed_official 59:2af474687369 442 }
mbed_official 59:2af474687369 443
mbed_official 59:2af474687369 444 if (buffer && !is_aligned(buffer,4)) {
mbed_official 59:2af474687369 445 // Copy unaligned data to write-buffer before USBD_Write
mbed_official 59:2af474687369 446 memcpy(ep_state[EP0IN].data_buf, buffer, size);
mbed_official 59:2af474687369 447 ret = USBD_Write(0, ep_state[EP0IN].data_buf, size, cb);
mbed_official 59:2af474687369 448 } else {
mbed_official 59:2af474687369 449 ret = USBD_Write(0, buffer, size, cb);
mbed_official 59:2af474687369 450 }
mbed_official 59:2af474687369 451
mbed_official 59:2af474687369 452 if (ret != USB_STATUS_OK) {
mbed_official 59:2af474687369 453 TRACE("FAILED - ret %d", ret);
mbed_official 59:2af474687369 454 }
mbed_official 59:2af474687369 455 }
mbed_official 59:2af474687369 456
mbed_official 59:2af474687369 457 void USBHAL::EP0stall(void)
mbed_official 59:2af474687369 458 {
mbed_official 59:2af474687369 459 TRACE_FUNC_IN;
mbed_official 59:2af474687369 460 USBD_StallEp0();
mbed_official 59:2af474687369 461 }
mbed_official 59:2af474687369 462
mbed_official 59:2af474687369 463 static EP_STATUS internEndpointRead(uint8_t ep, uint32_t maxSize)
mbed_official 59:2af474687369 464 {
mbed_official 59:2af474687369 465 //TRACE_FUNC_IN_P("endpoint 0x%x, size %ld, cb %d", (unsigned)ep, maxSize, useCallback);
mbed_official 59:2af474687369 466
mbed_official 59:2af474687369 467 if (ep >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 468 EFM_ASSERT(false);
mbed_official 59:2af474687369 469 return EP_INVALID;
mbed_official 59:2af474687369 470 }
mbed_official 59:2af474687369 471
mbed_official 59:2af474687369 472 ep_state[ep].status = READ_PENDING;
mbed_official 59:2af474687369 473
mbed_official 59:2af474687369 474 int ret = USBD_Read(USB_EP_TO_ADDR(ep), ep_state[ep].data_buf, maxSize,
mbed_official 59:2af474687369 475 ep_state[ep].intern_cb);
mbed_official 59:2af474687369 476
mbed_official 59:2af474687369 477 if (ret == USB_STATUS_OK) {
mbed_official 59:2af474687369 478 return EP_PENDING;
mbed_official 59:2af474687369 479 } else {
mbed_official 59:2af474687369 480 TRACE("FAILED - ret %d", ret);
mbed_official 59:2af474687369 481
mbed_official 59:2af474687369 482 if (ret == USB_STATUS_EP_STALLED) {
mbed_official 59:2af474687369 483 return EP_STALLED;
mbed_official 59:2af474687369 484 } else {
mbed_official 59:2af474687369 485 return EP_INVALID;
mbed_official 59:2af474687369 486 }
mbed_official 59:2af474687369 487 }
mbed_official 59:2af474687369 488 }
mbed_official 59:2af474687369 489
mbed_official 59:2af474687369 490 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
mbed_official 59:2af474687369 491 {
mbed_official 59:2af474687369 492 return internEndpointRead(endpoint, maximumSize);
mbed_official 59:2af474687369 493 }
mbed_official 59:2af474687369 494
mbed_official 59:2af474687369 495 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead)
mbed_official 59:2af474687369 496 {
mbed_official 59:2af474687369 497 TRACE_FUNC_IN;
mbed_official 59:2af474687369 498
mbed_official 59:2af474687369 499 if (endpoint >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 500 EFM_ASSERT(false);
mbed_official 59:2af474687369 501 return EP_INVALID;
mbed_official 59:2af474687369 502 }
mbed_official 59:2af474687369 503
mbed_official 59:2af474687369 504 EFM_ASSERT(data);
mbed_official 59:2af474687369 505 EFM_ASSERT(bytesRead);
mbed_official 59:2af474687369 506 if (!data || !bytesRead) {
mbed_official 59:2af474687369 507 return EP_INVALID;
mbed_official 59:2af474687369 508 }
mbed_official 59:2af474687369 509
mbed_official 59:2af474687369 510 switch (ep_state[endpoint].status) {
mbed_official 59:2af474687369 511 case READ_PENDING:
mbed_official 59:2af474687369 512 return EP_PENDING;
mbed_official 59:2af474687369 513
mbed_official 59:2af474687369 514 case READ_COMPLETE:
mbed_official 59:2af474687369 515 memcpy(data, ep_state[endpoint].data_buf, ep_state[endpoint].byte_count);
mbed_official 59:2af474687369 516 *bytesRead = ep_state[endpoint].byte_count;
mbed_official 59:2af474687369 517 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 518 return EP_COMPLETED;
mbed_official 59:2af474687369 519
mbed_official 59:2af474687369 520 case FAILED_STALLED:
mbed_official 59:2af474687369 521 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 522 return EP_STALLED;
mbed_official 59:2af474687369 523
mbed_official 59:2af474687369 524 default:
mbed_official 59:2af474687369 525 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 526 return EP_INVALID;
mbed_official 59:2af474687369 527 }
mbed_official 59:2af474687369 528 }
mbed_official 59:2af474687369 529
mbed_official 59:2af474687369 530 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
mbed_official 59:2af474687369 531 {
mbed_official 59:2af474687369 532 TRACE_FUNC_IN_P("endpoint 0x%x, data 0x%lx, size %lu", (unsigned )endpoint, (uint32_t)data, size);
mbed_official 59:2af474687369 533
mbed_official 59:2af474687369 534 EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
mbed_official 59:2af474687369 535 EFM_ASSERT(endpoint > EP0IN);
mbed_official 59:2af474687369 536 EFM_ASSERT(size <= ep_state[endpoint].max_packet);
mbed_official 59:2af474687369 537 EFM_ASSERT(data);
mbed_official 59:2af474687369 538
mbed_official 59:2af474687369 539 uint8_t ep = USB_EP_TO_INDEX(endpoint);
mbed_official 59:2af474687369 540
mbed_official 59:2af474687369 541 if (endpoint >= NUMBER_OF_ENDPOINTS || endpoint <= EP0IN) {
mbed_official 59:2af474687369 542 return EP_INVALID;
mbed_official 59:2af474687369 543 }
mbed_official 59:2af474687369 544
mbed_official 59:2af474687369 545 if (size > ep_state[endpoint].max_packet) {
mbed_official 59:2af474687369 546 return EP_INVALID;
mbed_official 59:2af474687369 547 }
mbed_official 59:2af474687369 548
mbed_official 59:2af474687369 549 if (!data) {
mbed_official 59:2af474687369 550 return EP_INVALID;
mbed_official 59:2af474687369 551 }
mbed_official 59:2af474687369 552
mbed_official 59:2af474687369 553 memcpy(ep_state[ep].data_buf, data, size);
mbed_official 59:2af474687369 554
mbed_official 59:2af474687369 555 ep_state[ep].status = WRITE_PENDING;
mbed_official 59:2af474687369 556 int ret = USBD_Write(USB_EP_TO_ADDR(endpoint), ep_state[ep].data_buf, size, ep_state[ep].intern_cb);
mbed_official 59:2af474687369 557
mbed_official 59:2af474687369 558 if (ret == USB_STATUS_EP_STALLED) {
mbed_official 59:2af474687369 559 ep_state[ep].status = IDLE;
mbed_official 59:2af474687369 560 return EP_STALLED;
mbed_official 59:2af474687369 561 } else if (ret != USB_STATUS_OK) {
mbed_official 59:2af474687369 562 ep_state[ep].status = IDLE;
mbed_official 59:2af474687369 563 return EP_INVALID;
mbed_official 59:2af474687369 564 }
mbed_official 59:2af474687369 565
mbed_official 59:2af474687369 566 return EP_PENDING;
mbed_official 59:2af474687369 567 }
mbed_official 59:2af474687369 568
mbed_official 59:2af474687369 569 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
mbed_official 59:2af474687369 570 {
mbed_official 59:2af474687369 571 if (endpoint >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 572 EFM_ASSERT(false);
mbed_official 59:2af474687369 573 return EP_INVALID;
mbed_official 59:2af474687369 574 }
mbed_official 59:2af474687369 575
mbed_official 59:2af474687369 576 switch (ep_state[endpoint].status) {
mbed_official 59:2af474687369 577 case WRITE_PENDING:
mbed_official 59:2af474687369 578 return EP_PENDING;
mbed_official 59:2af474687369 579
mbed_official 59:2af474687369 580 case WRITE_COMPLETE:
mbed_official 59:2af474687369 581 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 582 return EP_COMPLETED;
mbed_official 59:2af474687369 583
mbed_official 59:2af474687369 584 case FAILED_STALLED:
mbed_official 59:2af474687369 585 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 586 return EP_STALLED;
mbed_official 59:2af474687369 587
mbed_official 59:2af474687369 588 default:
mbed_official 59:2af474687369 589 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 590 return EP_INVALID;
mbed_official 59:2af474687369 591 }
mbed_official 59:2af474687369 592 }
mbed_official 59:2af474687369 593
mbed_official 59:2af474687369 594 void USBHAL::stallEndpoint(uint8_t endpoint)
mbed_official 59:2af474687369 595 {
mbed_official 59:2af474687369 596 TRACE_FUNC_IN;
mbed_official 59:2af474687369 597
mbed_official 59:2af474687369 598 EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
mbed_official 59:2af474687369 599 EFM_ASSERT((endpoint != EP0OUT) && (endpoint != EP0IN));
mbed_official 59:2af474687369 600
mbed_official 59:2af474687369 601 USBD_StallEp(USB_EP_TO_ADDR(endpoint));
mbed_official 59:2af474687369 602 }
mbed_official 59:2af474687369 603
mbed_official 59:2af474687369 604 void USBHAL::unstallEndpoint(uint8_t endpoint)
mbed_official 59:2af474687369 605 {
mbed_official 59:2af474687369 606 TRACE_FUNC_IN;
mbed_official 59:2af474687369 607
mbed_official 59:2af474687369 608 EFM_ASSERT(endpoint < NUMBER_OF_ENDPOINTS);
mbed_official 59:2af474687369 609 EFM_ASSERT((endpoint != EP0OUT) && (endpoint != EP0IN));
mbed_official 59:2af474687369 610
mbed_official 59:2af474687369 611 USBD_UnStallEp(USB_EP_TO_ADDR(endpoint));
mbed_official 59:2af474687369 612 }
mbed_official 59:2af474687369 613
mbed_official 59:2af474687369 614 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
mbed_official 59:2af474687369 615 {
mbed_official 59:2af474687369 616 TRACE_FUNC_IN_P("endpoint %d, packetsize %ld, options 0x%lx", endpoint,
mbed_official 59:2af474687369 617 maxPacket, options);
mbed_official 59:2af474687369 618
mbed_official 59:2af474687369 619 int mult = 1; // RX/TX buffer size multiplier
mbed_official 59:2af474687369 620 int type = USB_EPTYPE_INTR;
mbed_official 59:2af474687369 621
mbed_official 59:2af474687369 622 if (endpoint >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 623 EFM_ASSERT(false);
mbed_official 59:2af474687369 624 return false;
mbed_official 59:2af474687369 625 }
mbed_official 59:2af474687369 626
mbed_official 59:2af474687369 627 if (endpoint == EP0IN || endpoint == EP0OUT) {
mbed_official 59:2af474687369 628 EFM_ASSERT(false);
mbed_official 59:2af474687369 629 return false;
mbed_official 59:2af474687369 630 }
mbed_official 59:2af474687369 631
mbed_official 59:2af474687369 632 ep_state[endpoint].max_packet = 0;
mbed_official 59:2af474687369 633
mbed_official 59:2af474687369 634 if (endpoint == EPISO_OUT || endpoint == EPISO_IN) {
mbed_official 59:2af474687369 635 if (maxPacket > MAX_PACKET_SIZE_EPISO) {
mbed_official 59:2af474687369 636 EFM_ASSERT(false);
mbed_official 59:2af474687369 637 return false;
mbed_official 59:2af474687369 638 }
mbed_official 59:2af474687369 639 } else if ((maxPacket > MAX_PACKET_SIZE_EPBULK) || (maxPacket > MAX_PACKET_SIZE_EPINT)) {
mbed_official 59:2af474687369 640 EFM_ASSERT(false);
mbed_official 59:2af474687369 641 return false;
mbed_official 59:2af474687369 642 }
mbed_official 59:2af474687369 643
mbed_official 59:2af474687369 644 // USBDevice performs a read right after creating the endpoints,
mbed_official 59:2af474687369 645 // before calling configureDevice. The read will fail since
mbed_official 59:2af474687369 646 // at that point the device state is still ADDRESSED. Workaround
mbed_official 59:2af474687369 647 // is to force configured state here.
mbed_official 59:2af474687369 648 //
mbed_official 59:2af474687369 649 // This relies on USBDevice to not call realiseEndpoint unless
mbed_official 59:2af474687369 650 // it is transitioning to the CONFIGURED state.
mbed_official 59:2af474687369 651 USBD_SetUsbState(USBD_STATE_CONFIGURED);
mbed_official 59:2af474687369 652
mbed_official 59:2af474687369 653 // Why doesn't this function have a type param? This is silly...
mbed_official 59:2af474687369 654 switch (endpoint) {
mbed_official 59:2af474687369 655 case EPBULK_OUT:
mbed_official 59:2af474687369 656 case EPBULK_IN:
mbed_official 59:2af474687369 657 type = USB_EPTYPE_BULK;
mbed_official 59:2af474687369 658 mult = 2;
mbed_official 59:2af474687369 659 break;
mbed_official 59:2af474687369 660 case EPINT_OUT:
mbed_official 59:2af474687369 661 case EPINT_IN:
mbed_official 59:2af474687369 662 type = USB_EPTYPE_INTR;
mbed_official 59:2af474687369 663 mult = 1;
mbed_official 59:2af474687369 664 break;
mbed_official 59:2af474687369 665 case EPISO_OUT:
mbed_official 59:2af474687369 666 case EPISO_IN:
mbed_official 59:2af474687369 667 type = USB_EPTYPE_ISOC;
mbed_official 59:2af474687369 668 mult = 2; // ?
mbed_official 59:2af474687369 669 break;
mbed_official 59:2af474687369 670 }
mbed_official 59:2af474687369 671
mbed_official 59:2af474687369 672 // Some options force the endpoint to a specific type
mbed_official 59:2af474687369 673 if( options & ISOCHRONOUS ) {
mbed_official 59:2af474687369 674 type = USB_EPTYPE_ISOC;
mbed_official 59:2af474687369 675 mult = 2; // ?
mbed_official 59:2af474687369 676 } else if ( options & RATE_FEEDBACK_MODE ) {
mbed_official 59:2af474687369 677 // No support for whatever rate feedback is, but for interrupt only
mbed_official 59:2af474687369 678 type = USB_EPTYPE_INTR;
mbed_official 59:2af474687369 679 mult = 1;
mbed_official 59:2af474687369 680 }
mbed_official 59:2af474687369 681
mbed_official 59:2af474687369 682 #ifdef USB_USE_DYNAMIC_MEMORY
mbed_official 59:2af474687369 683 if (ep_state[endpoint].data_buf) {
mbed_official 59:2af474687369 684 free(ep_state[endpoint].data_buf);
mbed_official 59:2af474687369 685 }
mbed_official 59:2af474687369 686
mbed_official 59:2af474687369 687 ep_state[endpoint].data_buf = (uint8_t *)malloc(maxPacket);
mbed_official 59:2af474687369 688
mbed_official 59:2af474687369 689 if (!ep_state[endpoint].data_buf) {
mbed_official 59:2af474687369 690 EFM_ASSERT(false);
mbed_official 59:2af474687369 691 return false;
mbed_official 59:2af474687369 692 }
mbed_official 59:2af474687369 693 #endif
mbed_official 59:2af474687369 694
mbed_official 59:2af474687369 695 int ret = USBD_AddEndpoint(USB_EP_TO_ADDR(endpoint), type, maxPacket, mult);
mbed_official 59:2af474687369 696
mbed_official 59:2af474687369 697 if (ret == USB_STATUS_OK) {
mbed_official 59:2af474687369 698 ep_state[endpoint].status = IDLE;
mbed_official 59:2af474687369 699 ep_state[endpoint].max_packet = maxPacket;
mbed_official 59:2af474687369 700 return true;
mbed_official 59:2af474687369 701 } else {
mbed_official 59:2af474687369 702 return false;
mbed_official 59:2af474687369 703 }
mbed_official 59:2af474687369 704 }
mbed_official 59:2af474687369 705
mbed_official 59:2af474687369 706 bool USBHAL::getEndpointStallState(unsigned char endpoint)
mbed_official 59:2af474687369 707 {
mbed_official 59:2af474687369 708 TRACE_FUNC_IN;
mbed_official 59:2af474687369 709 if (endpoint >= NUMBER_OF_ENDPOINTS) {
mbed_official 59:2af474687369 710 EFM_ASSERT(false);
mbed_official 59:2af474687369 711 return false;
mbed_official 59:2af474687369 712 }
mbed_official 59:2af474687369 713 return USBD_EpIsStalled(USB_EP_TO_ADDR(endpoint));
mbed_official 59:2af474687369 714 }
mbed_official 59:2af474687369 715
mbed_official 59:2af474687369 716 static void run_cmd(USBISRCommand cmd, uint32_t param)
mbed_official 59:2af474687369 717 {
mbed_official 59:2af474687369 718 if (usb_isrcmd != CMD_HANDLED || cmd >= CMD_ENUM_END_MARKER) {
mbed_official 59:2af474687369 719 EFM_ASSERT(false);
mbed_official 59:2af474687369 720 abort();
mbed_official 59:2af474687369 721 }
mbed_official 59:2af474687369 722
mbed_official 59:2af474687369 723 usb_isrcmd = cmd;
mbed_official 59:2af474687369 724 usb_isrcmd_param = param;
mbed_official 59:2af474687369 725 isrptr();
mbed_official 59:2af474687369 726 }
mbed_official 59:2af474687369 727
mbed_official 59:2af474687369 728 void USBHAL::_usbisr(void)
mbed_official 59:2af474687369 729 {
mbed_official 59:2af474687369 730 EFM_ASSERT(instance);
mbed_official 59:2af474687369 731 instance->usbisr();
mbed_official 59:2af474687369 732 }
mbed_official 59:2af474687369 733
mbed_official 59:2af474687369 734 void USBHAL::usbisr(void)
mbed_official 59:2af474687369 735 {
mbed_official 59:2af474687369 736 //TRACE_FUNC_IN;
mbed_official 59:2af474687369 737
mbed_official 59:2af474687369 738 // This "ISR" is used just to route callbacks from SiL USB driver
mbed_official 59:2af474687369 739 // callback context (which can not call protected/private USBHAL
mbed_official 59:2af474687369 740 // methods), to the actual USBHAL.
mbed_official 59:2af474687369 741
mbed_official 59:2af474687369 742 EFM_ASSERT(usb_isrcmd != CMD_HANDLED);
mbed_official 59:2af474687369 743 switch (usb_isrcmd) {
mbed_official 59:2af474687369 744 case CMD_EP0SETUP:
mbed_official 59:2af474687369 745 this->EP0setupCallback();
mbed_official 59:2af474687369 746 break;
mbed_official 59:2af474687369 747 case CMD_EP0IN:
mbed_official 59:2af474687369 748 this->EP0in();
mbed_official 59:2af474687369 749 break;
mbed_official 59:2af474687369 750 case CMD_EP0OUT:
mbed_official 59:2af474687369 751 this->EP0out();
mbed_official 59:2af474687369 752 break;
mbed_official 59:2af474687369 753 case CMD_BUSRESET:
mbed_official 59:2af474687369 754 this->busReset();
mbed_official 59:2af474687369 755 break;
mbed_official 59:2af474687369 756 case CMD_EP_XFER_COMPLETED:
mbed_official 59:2af474687369 757 if (epCallback[usb_isrcmd_param] && instance) {
mbed_official 59:2af474687369 758 (instance->*(epCallback[usb_isrcmd_param]))();
mbed_official 59:2af474687369 759 }
mbed_official 59:2af474687369 760 break;
mbed_official 59:2af474687369 761 case CMD_SOF:
mbed_official 59:2af474687369 762 this->SOF(usb_isrcmd_param);
mbed_official 59:2af474687369 763 break;
mbed_official 59:2af474687369 764 case CMD_SUSPEND_STATE_CHANGED:
mbed_official 59:2af474687369 765 this->suspendStateChanged(usb_isrcmd_param);
mbed_official 59:2af474687369 766 break;
mbed_official 59:2af474687369 767 default:
mbed_official 59:2af474687369 768 EFM_ASSERT(false);
mbed_official 59:2af474687369 769 break;
mbed_official 59:2af474687369 770 }
mbed_official 59:2af474687369 771 usb_isrcmd = CMD_HANDLED;
mbed_official 59:2af474687369 772 }
mbed_official 59:2af474687369 773 #endif
mbed_official 59:2af474687369 774
mbed_official 59:2af474687369 775 // End of file