USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
muraguchi
Date:
Tue Feb 09 12:00:34 2021 +0000
Revision:
72:c80da04112fd
Parent:
71:53949e6131f6
Initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 71:53949e6131f6 1 /*******************************************************************************
Kojto 71:53949e6131f6 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
Kojto 71:53949e6131f6 3 *
Kojto 71:53949e6131f6 4 * Permission is hereby granted, free of charge, to any person obtaining a
Kojto 71:53949e6131f6 5 * copy of this software and associated documentation files (the "Software"),
Kojto 71:53949e6131f6 6 * to deal in the Software without restriction, including without limitation
Kojto 71:53949e6131f6 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Kojto 71:53949e6131f6 8 * and/or sell copies of the Software, and to permit persons to whom the
Kojto 71:53949e6131f6 9 * Software is furnished to do so, subject to the following conditions:
Kojto 71:53949e6131f6 10 *
Kojto 71:53949e6131f6 11 * The above copyright notice and this permission notice shall be included
Kojto 71:53949e6131f6 12 * in all copies or substantial portions of the Software.
Kojto 71:53949e6131f6 13 *
Kojto 71:53949e6131f6 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Kojto 71:53949e6131f6 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Kojto 71:53949e6131f6 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Kojto 71:53949e6131f6 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Kojto 71:53949e6131f6 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Kojto 71:53949e6131f6 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Kojto 71:53949e6131f6 20 * OTHER DEALINGS IN THE SOFTWARE.
Kojto 71:53949e6131f6 21 *
Kojto 71:53949e6131f6 22 * Except as contained in this notice, the name of Maxim Integrated
Kojto 71:53949e6131f6 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Kojto 71:53949e6131f6 24 * Products, Inc. Branding Policy.
Kojto 71:53949e6131f6 25 *
Kojto 71:53949e6131f6 26 * The mere transfer of this software does not imply any licenses
Kojto 71:53949e6131f6 27 * of trade secrets, proprietary technology, copyrights, patents,
Kojto 71:53949e6131f6 28 * trademarks, maskwork rights, or any other form of intellectual
Kojto 71:53949e6131f6 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
Kojto 71:53949e6131f6 30 * ownership rights.
Kojto 71:53949e6131f6 31 *******************************************************************************
Kojto 71:53949e6131f6 32 */
Kojto 71:53949e6131f6 33
Kojto 71:53949e6131f6 34 #if defined(TARGET_Maxim)
Kojto 71:53949e6131f6 35
Kojto 71:53949e6131f6 36 #include "USBHAL.h"
Kojto 71:53949e6131f6 37 #include "usb_regs.h"
Kojto 71:53949e6131f6 38 #include "clkman_regs.h"
Kojto 71:53949e6131f6 39
Kojto 71:53949e6131f6 40 #if defined(TARGET_MAX32625) || defined(TARGET_MAX32630)
Kojto 71:53949e6131f6 41 #include "pwrman_regs.h"
Kojto 71:53949e6131f6 42 #endif
Kojto 71:53949e6131f6 43
Kojto 71:53949e6131f6 44 #define CONNECT_INTS (MXC_F_USB_DEV_INTEN_BRST | MXC_F_USB_DEV_INTEN_SETUP | MXC_F_USB_DEV_INTEN_EP_IN | MXC_F_USB_DEV_INTEN_EP_OUT | MXC_F_USB_DEV_INTEN_DMA_ERR)
Kojto 71:53949e6131f6 45
Kojto 71:53949e6131f6 46 USBHAL *USBHAL::instance;
Kojto 71:53949e6131f6 47
Kojto 71:53949e6131f6 48 typedef struct {
Kojto 71:53949e6131f6 49 volatile uint32_t buf0_desc;
Kojto 71:53949e6131f6 50 volatile uint32_t buf0_address;
Kojto 71:53949e6131f6 51 volatile uint32_t buf1_desc;
Kojto 71:53949e6131f6 52 volatile uint32_t buf1_address;
Kojto 71:53949e6131f6 53 } ep_buffer_t;
Kojto 71:53949e6131f6 54
Kojto 71:53949e6131f6 55 typedef struct {
Kojto 71:53949e6131f6 56 ep_buffer_t out_buffer;
Kojto 71:53949e6131f6 57 ep_buffer_t in_buffer;
Kojto 71:53949e6131f6 58 } ep0_buffer_t;
Kojto 71:53949e6131f6 59
Kojto 71:53949e6131f6 60 typedef struct {
Kojto 71:53949e6131f6 61 ep0_buffer_t ep0;
Kojto 71:53949e6131f6 62 ep_buffer_t ep[MXC_USB_NUM_EP - 1];
Kojto 71:53949e6131f6 63 } ep_buffer_descriptor_t;
Kojto 71:53949e6131f6 64
Kojto 71:53949e6131f6 65 // Static storage for endpoint buffer descriptor table. Must be 512 byte aligned for DMA.
Kojto 71:53949e6131f6 66 #ifdef __IAR_SYSTEMS_ICC__
Kojto 71:53949e6131f6 67 #pragma data_alignment = 512
Kojto 71:53949e6131f6 68 #else
Kojto 71:53949e6131f6 69 __attribute__ ((aligned (512)))
Kojto 71:53949e6131f6 70 #endif
Kojto 71:53949e6131f6 71 ep_buffer_descriptor_t ep_buffer_descriptor;
Kojto 71:53949e6131f6 72
Kojto 71:53949e6131f6 73 // static storage for temporary data buffers. Must be 32 byte aligned.
Kojto 71:53949e6131f6 74 #ifdef __IAR_SYSTEMS_ICC__
Kojto 71:53949e6131f6 75 #pragma data_alignment = 4
Kojto 71:53949e6131f6 76 #else
Kojto 71:53949e6131f6 77 __attribute__ ((aligned (4)))
Kojto 71:53949e6131f6 78 #endif
Kojto 71:53949e6131f6 79 static uint8_t aligned_buffer[NUMBER_OF_LOGICAL_ENDPOINTS][MXC_USB_MAX_PACKET];
Kojto 71:53949e6131f6 80
Kojto 71:53949e6131f6 81 // control packet state
Kojto 71:53949e6131f6 82 static enum {
Kojto 71:53949e6131f6 83 CTRL_NONE = 0,
Kojto 71:53949e6131f6 84 CTRL_SETUP,
Kojto 71:53949e6131f6 85 CTRL_OUT,
Kojto 71:53949e6131f6 86 CTRL_IN,
Kojto 71:53949e6131f6 87 } control_state;
Kojto 71:53949e6131f6 88
Kojto 71:53949e6131f6 89 USBHAL::USBHAL(void)
Kojto 71:53949e6131f6 90 {
Kojto 71:53949e6131f6 91 NVIC_DisableIRQ(USB_IRQn);
Kojto 71:53949e6131f6 92
Kojto 71:53949e6131f6 93 #if defined(TARGET_MAX32600)
Kojto 71:53949e6131f6 94 // The PLL must be enabled for USB
Kojto 71:53949e6131f6 95 MBED_ASSERT(MXC_CLKMAN->clk_config & MXC_F_CLKMAN_CLK_CONFIG_PLL_ENABLE);
Kojto 71:53949e6131f6 96
Kojto 71:53949e6131f6 97 // Enable the USB clock
Kojto 71:53949e6131f6 98 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_GATE_N;
Kojto 71:53949e6131f6 99 #elif defined(TARGET_MAX32620)
Kojto 71:53949e6131f6 100 // Enable the USB clock
Kojto 71:53949e6131f6 101 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE;
Kojto 71:53949e6131f6 102 #endif
Kojto 71:53949e6131f6 103
Kojto 71:53949e6131f6 104 // reset the device
Kojto 71:53949e6131f6 105 MXC_USB->cn = 0;
Kojto 71:53949e6131f6 106 MXC_USB->cn = MXC_F_USB_CN_USB_EN;
Kojto 71:53949e6131f6 107 MXC_USB->dev_inten = 0;
Kojto 71:53949e6131f6 108 MXC_USB->dev_cn = 0;
Kojto 71:53949e6131f6 109 MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST;
Kojto 71:53949e6131f6 110 MXC_USB->dev_cn = 0;
Kojto 71:53949e6131f6 111
Kojto 71:53949e6131f6 112 // fill in callback arrays
Kojto 71:53949e6131f6 113 epCallback[EP0OUT] = NULL;
Kojto 71:53949e6131f6 114 epCallback[EP0IN] = NULL;
Kojto 71:53949e6131f6 115 epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
Kojto 71:53949e6131f6 116 epCallback[EP1IN ] = &USBHAL::EP1_IN_callback;
Kojto 71:53949e6131f6 117 epCallback[EP2OUT] = &USBHAL::EP2_OUT_callback;
Kojto 71:53949e6131f6 118 epCallback[EP2IN ] = &USBHAL::EP2_IN_callback;
Kojto 71:53949e6131f6 119 epCallback[EP3OUT] = &USBHAL::EP3_OUT_callback;
Kojto 71:53949e6131f6 120 epCallback[EP3IN ] = &USBHAL::EP3_IN_callback;
Kojto 71:53949e6131f6 121 epCallback[EP4OUT] = &USBHAL::EP4_OUT_callback;
Kojto 71:53949e6131f6 122 epCallback[EP4IN ] = &USBHAL::EP4_IN_callback;
Kojto 71:53949e6131f6 123 epCallback[EP5OUT] = &USBHAL::EP5_OUT_callback;
Kojto 71:53949e6131f6 124 epCallback[EP5IN ] = &USBHAL::EP5_IN_callback;
Kojto 71:53949e6131f6 125 epCallback[EP6OUT] = &USBHAL::EP6_OUT_callback;
Kojto 71:53949e6131f6 126 epCallback[EP6IN ] = &USBHAL::EP6_IN_callback;
Kojto 71:53949e6131f6 127 epCallback[EP7OUT] = &USBHAL::EP7_OUT_callback;
Kojto 71:53949e6131f6 128 epCallback[EP7IN ] = &USBHAL::EP7_IN_callback;
Kojto 71:53949e6131f6 129
Kojto 71:53949e6131f6 130 // clear driver state
Kojto 71:53949e6131f6 131 control_state = CTRL_NONE;
Kojto 71:53949e6131f6 132
Kojto 71:53949e6131f6 133 // set the descriptor location
Kojto 71:53949e6131f6 134 MXC_USB->ep_base = (uint32_t)&ep_buffer_descriptor;
Kojto 71:53949e6131f6 135
Kojto 71:53949e6131f6 136 // enable VBUS interrupts
Kojto 71:53949e6131f6 137 MXC_USB->dev_inten = MXC_F_USB_DEV_INTEN_NO_VBUS | MXC_F_USB_DEV_INTEN_VBUS;
Kojto 71:53949e6131f6 138
Kojto 71:53949e6131f6 139 // attach IRQ handler and enable interrupts
Kojto 71:53949e6131f6 140 instance = this;
Kojto 71:53949e6131f6 141 NVIC_SetVector(USB_IRQn, &_usbisr);
Kojto 71:53949e6131f6 142 NVIC_EnableIRQ(USB_IRQn);
Kojto 71:53949e6131f6 143 }
Kojto 71:53949e6131f6 144
Kojto 71:53949e6131f6 145 USBHAL::~USBHAL(void)
Kojto 71:53949e6131f6 146 {
Kojto 71:53949e6131f6 147 MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST;
Kojto 71:53949e6131f6 148 MXC_USB->dev_cn = 0;
Kojto 71:53949e6131f6 149 MXC_USB->cn = 0;
Kojto 71:53949e6131f6 150 }
Kojto 71:53949e6131f6 151
Kojto 71:53949e6131f6 152 void USBHAL::connect(void)
Kojto 71:53949e6131f6 153 {
Kojto 71:53949e6131f6 154 // enable interrupts
Kojto 71:53949e6131f6 155 MXC_USB->dev_inten |= CONNECT_INTS;
Kojto 71:53949e6131f6 156
Kojto 71:53949e6131f6 157 // allow interrupts on ep0
Kojto 71:53949e6131f6 158 MXC_USB->ep[0] |= MXC_F_USB_EP_INT_EN;
Kojto 71:53949e6131f6 159
Kojto 71:53949e6131f6 160 // pullup enable
Kojto 71:53949e6131f6 161 MXC_USB->dev_cn |= (MXC_F_USB_DEV_CN_CONNECT | MXC_F_USB_DEV_CN_FIFO_MODE);
Kojto 71:53949e6131f6 162 }
Kojto 71:53949e6131f6 163
Kojto 71:53949e6131f6 164 void USBHAL::disconnect(void)
Kojto 71:53949e6131f6 165 {
Kojto 71:53949e6131f6 166 // disable interrupts
Kojto 71:53949e6131f6 167 MXC_USB->dev_inten &= ~CONNECT_INTS;
Kojto 71:53949e6131f6 168
Kojto 71:53949e6131f6 169 // disable pullup
Kojto 71:53949e6131f6 170 MXC_USB->dev_cn &= ~MXC_F_USB_DEV_CN_CONNECT;
Kojto 71:53949e6131f6 171 }
Kojto 71:53949e6131f6 172
Kojto 71:53949e6131f6 173 void USBHAL::configureDevice(void)
Kojto 71:53949e6131f6 174 {
Kojto 71:53949e6131f6 175 // do nothing
Kojto 71:53949e6131f6 176 }
Kojto 71:53949e6131f6 177
Kojto 71:53949e6131f6 178 void USBHAL::unconfigureDevice(void)
Kojto 71:53949e6131f6 179 {
Kojto 71:53949e6131f6 180 // reset endpoints
Kojto 71:53949e6131f6 181 for (int i = 0; i < MXC_USB_NUM_EP; i++) {
Kojto 71:53949e6131f6 182 // Disable endpoint and clear the data toggle
Kojto 71:53949e6131f6 183 MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR;
Kojto 71:53949e6131f6 184 MXC_USB->ep[i] |= MXC_F_USB_EP_DT;
Kojto 71:53949e6131f6 185 }
Kojto 71:53949e6131f6 186 }
Kojto 71:53949e6131f6 187
Kojto 71:53949e6131f6 188 void USBHAL::setAddress(uint8_t address)
Kojto 71:53949e6131f6 189 {
Kojto 71:53949e6131f6 190 // do nothing
Kojto 71:53949e6131f6 191 }
Kojto 71:53949e6131f6 192
Kojto 71:53949e6131f6 193 void USBHAL::remoteWakeup(void)
Kojto 71:53949e6131f6 194 {
Kojto 71:53949e6131f6 195 // do nothing
Kojto 71:53949e6131f6 196 }
Kojto 71:53949e6131f6 197
Kojto 71:53949e6131f6 198 static ep_buffer_t *get_desc(uint8_t endpoint)
Kojto 71:53949e6131f6 199 {
Kojto 71:53949e6131f6 200 uint8_t epnum = EP_NUM(endpoint);
Kojto 71:53949e6131f6 201 ep_buffer_t *desc;
Kojto 71:53949e6131f6 202
Kojto 71:53949e6131f6 203 if (epnum == 0) {
Kojto 71:53949e6131f6 204 if (IN_EP(endpoint)) {
Kojto 71:53949e6131f6 205 desc = &ep_buffer_descriptor.ep0.in_buffer;
Kojto 71:53949e6131f6 206 } else {
Kojto 71:53949e6131f6 207 desc = &ep_buffer_descriptor.ep0.out_buffer;
Kojto 71:53949e6131f6 208 }
Kojto 71:53949e6131f6 209 } else {
Kojto 71:53949e6131f6 210 desc = &ep_buffer_descriptor.ep[epnum - 1];
Kojto 71:53949e6131f6 211 }
Kojto 71:53949e6131f6 212
Kojto 71:53949e6131f6 213 return desc;
Kojto 71:53949e6131f6 214 }
Kojto 71:53949e6131f6 215
Kojto 71:53949e6131f6 216 void USBHAL::EP0setup(uint8_t *buffer)
Kojto 71:53949e6131f6 217 {
Kojto 71:53949e6131f6 218 // Setup packet is fixed at 8 bytes
Kojto 71:53949e6131f6 219 // Setup registers cannot be read in byte mode
Kojto 71:53949e6131f6 220 uint32_t *ptr32 = (uint32_t*)buffer;
Kojto 71:53949e6131f6 221 ptr32[0] = (uint32_t)MXC_USB->setup0;
Kojto 71:53949e6131f6 222 ptr32[1] = (uint32_t)MXC_USB->setup1;
Kojto 71:53949e6131f6 223 }
Kojto 71:53949e6131f6 224
Kojto 71:53949e6131f6 225 void USBHAL::EP0read(void)
Kojto 71:53949e6131f6 226 {
Kojto 71:53949e6131f6 227 if (control_state == CTRL_IN) {
Kojto 71:53949e6131f6 228 // This is the status stage. ACK.
Kojto 71:53949e6131f6 229 MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK;
Kojto 71:53949e6131f6 230 control_state = CTRL_NONE;
Kojto 71:53949e6131f6 231 return;
Kojto 71:53949e6131f6 232 }
Kojto 71:53949e6131f6 233
Kojto 71:53949e6131f6 234 control_state = CTRL_OUT;
Kojto 71:53949e6131f6 235
Kojto 71:53949e6131f6 236 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
Kojto 71:53949e6131f6 237 }
Kojto 71:53949e6131f6 238
Kojto 71:53949e6131f6 239 void USBHAL::EP0readStage(void)
Kojto 71:53949e6131f6 240 {
Kojto 71:53949e6131f6 241 // do nothing
Kojto 71:53949e6131f6 242 }
Kojto 71:53949e6131f6 243
Kojto 71:53949e6131f6 244 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
Kojto 71:53949e6131f6 245 {
Kojto 71:53949e6131f6 246 uint32_t size;
Kojto 71:53949e6131f6 247
Kojto 71:53949e6131f6 248 if (MXC_USB->out_owner & 1) {
Kojto 71:53949e6131f6 249 return 0;
Kojto 71:53949e6131f6 250 }
Kojto 71:53949e6131f6 251
Kojto 71:53949e6131f6 252 // get the packet length and contents
Kojto 71:53949e6131f6 253 ep_buffer_t *desc = get_desc(EP0OUT);
Kojto 71:53949e6131f6 254 size = desc->buf0_desc;
Kojto 71:53949e6131f6 255 memcpy(buffer, aligned_buffer[0], size);
Kojto 71:53949e6131f6 256
Kojto 71:53949e6131f6 257 return size;
Kojto 71:53949e6131f6 258 }
Kojto 71:53949e6131f6 259
Kojto 71:53949e6131f6 260 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
Kojto 71:53949e6131f6 261 {
Kojto 71:53949e6131f6 262 if ((size == 0) && (control_state != CTRL_IN)) {
Kojto 71:53949e6131f6 263 // This is a status stage ACK. Handle in hardware.
Kojto 71:53949e6131f6 264 MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK;
Kojto 71:53949e6131f6 265 control_state = CTRL_NONE;
Kojto 71:53949e6131f6 266 return;
Kojto 71:53949e6131f6 267 }
Kojto 71:53949e6131f6 268
Kojto 71:53949e6131f6 269 control_state = CTRL_IN;
Kojto 71:53949e6131f6 270
Kojto 71:53949e6131f6 271 endpointWrite(EP0IN, buffer, size);
Kojto 71:53949e6131f6 272 }
Kojto 71:53949e6131f6 273
Kojto 71:53949e6131f6 274 void USBHAL::EP0stall(void)
Kojto 71:53949e6131f6 275 {
Kojto 71:53949e6131f6 276 stallEndpoint(0);
Kojto 71:53949e6131f6 277 }
Kojto 71:53949e6131f6 278
Kojto 71:53949e6131f6 279 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
Kojto 71:53949e6131f6 280 {
Kojto 71:53949e6131f6 281 uint8_t epnum = EP_NUM(endpoint);
Kojto 71:53949e6131f6 282
Kojto 71:53949e6131f6 283 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || IN_EP(endpoint)) {
Kojto 71:53949e6131f6 284 return EP_INVALID;
Kojto 71:53949e6131f6 285 }
Kojto 71:53949e6131f6 286
Kojto 71:53949e6131f6 287 if (maximumSize > MXC_USB_MAX_PACKET) {
Kojto 71:53949e6131f6 288 return EP_INVALID;
Kojto 71:53949e6131f6 289 }
Kojto 71:53949e6131f6 290
Kojto 71:53949e6131f6 291 uint32_t mask = (1 << epnum);
Kojto 71:53949e6131f6 292 if (MXC_USB->out_owner & mask) {
Kojto 71:53949e6131f6 293 return EP_INVALID;
Kojto 71:53949e6131f6 294 }
Kojto 71:53949e6131f6 295
Kojto 71:53949e6131f6 296 ep_buffer_t *desc = get_desc(endpoint);
Kojto 71:53949e6131f6 297 desc->buf0_desc = maximumSize;
Kojto 71:53949e6131f6 298 desc->buf0_address = (uint32_t)aligned_buffer[epnum];
Kojto 71:53949e6131f6 299
Kojto 71:53949e6131f6 300 MXC_USB->out_owner = mask;
Kojto 71:53949e6131f6 301
Kojto 71:53949e6131f6 302 return EP_PENDING;
Kojto 71:53949e6131f6 303 }
Kojto 71:53949e6131f6 304
Kojto 71:53949e6131f6 305 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead)
Kojto 71:53949e6131f6 306 {
Kojto 71:53949e6131f6 307 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || IN_EP(endpoint)) {
Kojto 71:53949e6131f6 308 return EP_INVALID;
Kojto 71:53949e6131f6 309 }
Kojto 71:53949e6131f6 310
Kojto 71:53949e6131f6 311 uint32_t mask = (1 << EP_NUM(endpoint));
Kojto 71:53949e6131f6 312 if (MXC_USB->out_owner & mask) {
Kojto 71:53949e6131f6 313 return EP_PENDING;
Kojto 71:53949e6131f6 314 }
Kojto 71:53949e6131f6 315
Kojto 71:53949e6131f6 316 // get the packet length and contents
Kojto 71:53949e6131f6 317 ep_buffer_t *desc = get_desc(endpoint);
Kojto 71:53949e6131f6 318 *bytesRead = desc->buf0_desc;
Kojto 71:53949e6131f6 319 memcpy(data, aligned_buffer[EP_NUM(endpoint)], *bytesRead);
Kojto 71:53949e6131f6 320
Kojto 71:53949e6131f6 321 return EP_COMPLETED;
Kojto 71:53949e6131f6 322 }
Kojto 71:53949e6131f6 323
Kojto 71:53949e6131f6 324 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
Kojto 71:53949e6131f6 325 {
Kojto 71:53949e6131f6 326 uint8_t epnum = EP_NUM(endpoint);
Kojto 71:53949e6131f6 327
Kojto 71:53949e6131f6 328 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || OUT_EP(endpoint)) {
Kojto 71:53949e6131f6 329 return EP_INVALID;
Kojto 71:53949e6131f6 330 }
Kojto 71:53949e6131f6 331
Kojto 71:53949e6131f6 332 if (size > MXC_USB_MAX_PACKET) {
Kojto 71:53949e6131f6 333 return EP_INVALID;
Kojto 71:53949e6131f6 334 }
Kojto 71:53949e6131f6 335
Kojto 71:53949e6131f6 336 uint32_t mask = (1 << epnum);
Kojto 71:53949e6131f6 337 if (MXC_USB->in_owner & mask) {
Kojto 71:53949e6131f6 338 return EP_INVALID;
Kojto 71:53949e6131f6 339 }
Kojto 71:53949e6131f6 340
Kojto 71:53949e6131f6 341 memcpy(aligned_buffer[epnum], data, size);
Kojto 71:53949e6131f6 342
Kojto 71:53949e6131f6 343 ep_buffer_t *desc = get_desc(endpoint);
Kojto 71:53949e6131f6 344 desc->buf0_desc = size;
Kojto 71:53949e6131f6 345 desc->buf0_address = (uint32_t)aligned_buffer[epnum];
Kojto 71:53949e6131f6 346
Kojto 71:53949e6131f6 347 // start the DMA
Kojto 71:53949e6131f6 348 MXC_USB->in_owner = mask;
Kojto 71:53949e6131f6 349
Kojto 71:53949e6131f6 350 return EP_PENDING;
Kojto 71:53949e6131f6 351 }
Kojto 71:53949e6131f6 352
Kojto 71:53949e6131f6 353 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
Kojto 71:53949e6131f6 354 {
Kojto 71:53949e6131f6 355 uint32_t mask = (1 << EP_NUM(endpoint));
Kojto 71:53949e6131f6 356 if (MXC_USB->in_owner & mask) {
Kojto 71:53949e6131f6 357 return EP_PENDING;
Kojto 71:53949e6131f6 358 }
Kojto 71:53949e6131f6 359
Kojto 71:53949e6131f6 360 return EP_COMPLETED;
Kojto 71:53949e6131f6 361 }
Kojto 71:53949e6131f6 362
Kojto 71:53949e6131f6 363 void USBHAL::stallEndpoint(uint8_t endpoint)
Kojto 71:53949e6131f6 364 {
Kojto 71:53949e6131f6 365 uint8_t epnum = EP_NUM(endpoint);
Kojto 71:53949e6131f6 366
Kojto 71:53949e6131f6 367 if (epnum == 0) {
Kojto 71:53949e6131f6 368 MXC_USB->ep[epnum] |= MXC_F_USB_EP_ST_STALL;
Kojto 71:53949e6131f6 369 }
Kojto 71:53949e6131f6 370
Kojto 71:53949e6131f6 371 MXC_USB->ep[epnum] |= MXC_F_USB_EP_STALL;
Kojto 71:53949e6131f6 372 }
Kojto 71:53949e6131f6 373
Kojto 71:53949e6131f6 374 void USBHAL::unstallEndpoint(uint8_t endpoint)
Kojto 71:53949e6131f6 375 {
Kojto 71:53949e6131f6 376 MXC_USB->ep[EP_NUM(endpoint)] &= ~MXC_F_USB_EP_STALL;
Kojto 71:53949e6131f6 377 }
Kojto 71:53949e6131f6 378
Kojto 71:53949e6131f6 379 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
Kojto 71:53949e6131f6 380 {
Kojto 71:53949e6131f6 381 uint8_t epnum = EP_NUM(endpoint);
Kojto 71:53949e6131f6 382 uint32_t ep_ctrl;
Kojto 71:53949e6131f6 383
Kojto 71:53949e6131f6 384 if (epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) {
Kojto 71:53949e6131f6 385 return false;
Kojto 71:53949e6131f6 386 }
Kojto 71:53949e6131f6 387
Kojto 71:53949e6131f6 388 if (IN_EP(endpoint)) {
Kojto 71:53949e6131f6 389 ep_ctrl = (MXC_V_USB_EP_DIR_IN << MXC_F_USB_EP_DIR_POS);
Kojto 71:53949e6131f6 390 } else {
Kojto 71:53949e6131f6 391 ep_ctrl = (MXC_S_USB_EP_DIR_OUT << MXC_F_USB_EP_DIR_POS);
Kojto 71:53949e6131f6 392 }
Kojto 71:53949e6131f6 393
Kojto 71:53949e6131f6 394 ep_ctrl |= (MXC_F_USB_EP_DT | MXC_F_USB_EP_INT_EN);
Kojto 71:53949e6131f6 395
Kojto 71:53949e6131f6 396 MXC_USB->ep[epnum] = ep_ctrl;
Kojto 71:53949e6131f6 397
Kojto 71:53949e6131f6 398 return true;
Kojto 71:53949e6131f6 399 }
Kojto 71:53949e6131f6 400
Kojto 71:53949e6131f6 401 bool USBHAL::getEndpointStallState(unsigned char endpoint)
Kojto 71:53949e6131f6 402 {
Kojto 71:53949e6131f6 403 return !!(MXC_USB->ep[endpoint] & MXC_F_USB_EP_STALL);
Kojto 71:53949e6131f6 404 }
Kojto 71:53949e6131f6 405
Kojto 71:53949e6131f6 406 void USBHAL::_usbisr(void)
Kojto 71:53949e6131f6 407 {
Kojto 71:53949e6131f6 408 instance->usbisr();
Kojto 71:53949e6131f6 409 }
Kojto 71:53949e6131f6 410
Kojto 71:53949e6131f6 411 void USBHAL::usbisr(void)
Kojto 71:53949e6131f6 412 {
Kojto 71:53949e6131f6 413 // get and clear irqs
Kojto 71:53949e6131f6 414 uint32_t irq_flags = MXC_USB->dev_intfl;
Kojto 71:53949e6131f6 415 MXC_USB->dev_intfl = irq_flags;
Kojto 71:53949e6131f6 416
Kojto 71:53949e6131f6 417 // process only enabled interrupts
Kojto 71:53949e6131f6 418 irq_flags &= MXC_USB->dev_inten;
Kojto 71:53949e6131f6 419
Kojto 71:53949e6131f6 420 // suspend
Kojto 71:53949e6131f6 421 if (irq_flags & MXC_F_USB_DEV_INTFL_SUSP) {
Kojto 71:53949e6131f6 422 suspendStateChanged(1);
Kojto 71:53949e6131f6 423 }
Kojto 71:53949e6131f6 424
Kojto 71:53949e6131f6 425 // bus reset
Kojto 71:53949e6131f6 426 if (irq_flags & MXC_F_USB_DEV_INTFL_BRST) {
Kojto 71:53949e6131f6 427
Kojto 71:53949e6131f6 428 // reset endpoints
Kojto 71:53949e6131f6 429 for (int i = 0; i < MXC_USB_NUM_EP; i++) {
Kojto 71:53949e6131f6 430 // Disable endpoint and clear the data toggle
Kojto 71:53949e6131f6 431 MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR;
Kojto 71:53949e6131f6 432 MXC_USB->ep[i] |= MXC_F_USB_EP_DT;
Kojto 71:53949e6131f6 433 }
Kojto 71:53949e6131f6 434
Kojto 71:53949e6131f6 435 // clear driver state
Kojto 71:53949e6131f6 436 control_state = CTRL_NONE;
Kojto 71:53949e6131f6 437
Kojto 71:53949e6131f6 438 busReset();
Kojto 71:53949e6131f6 439
Kojto 71:53949e6131f6 440 // no need to process events after reset
Kojto 71:53949e6131f6 441 return;
Kojto 71:53949e6131f6 442 }
Kojto 71:53949e6131f6 443
Kojto 71:53949e6131f6 444 // Setup packet
Kojto 71:53949e6131f6 445 if (irq_flags & MXC_F_USB_DEV_INTFL_SETUP) {
Kojto 71:53949e6131f6 446 control_state = CTRL_SETUP;
Kojto 71:53949e6131f6 447 EP0setupCallback();
Kojto 71:53949e6131f6 448 }
Kojto 71:53949e6131f6 449
Kojto 71:53949e6131f6 450 // IN packets
Kojto 71:53949e6131f6 451 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_IN) {
Kojto 71:53949e6131f6 452 // get and clear IN irqs
Kojto 71:53949e6131f6 453 uint32_t in_irqs = MXC_USB->in_int;
Kojto 71:53949e6131f6 454 MXC_USB->in_int = in_irqs;
Kojto 71:53949e6131f6 455
Kojto 71:53949e6131f6 456 if (in_irqs & 1) {
Kojto 71:53949e6131f6 457 EP0in();
Kojto 71:53949e6131f6 458 }
Kojto 71:53949e6131f6 459
Kojto 71:53949e6131f6 460 for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) {
Kojto 71:53949e6131f6 461 uint32_t irq_mask = (1 << epnum);
Kojto 71:53949e6131f6 462 if (in_irqs & irq_mask) {
Kojto 71:53949e6131f6 463 uint8_t endpoint = (epnum << 1) | DIR_IN;
Kojto 71:53949e6131f6 464 (instance->*(epCallback[endpoint]))();
Kojto 71:53949e6131f6 465 }
Kojto 71:53949e6131f6 466 }
Kojto 71:53949e6131f6 467 }
Kojto 71:53949e6131f6 468
Kojto 71:53949e6131f6 469 // OUT packets
Kojto 71:53949e6131f6 470 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_OUT) {
Kojto 71:53949e6131f6 471 // get and clear OUT irqs
Kojto 71:53949e6131f6 472 uint32_t out_irqs = MXC_USB->out_int;
Kojto 71:53949e6131f6 473 MXC_USB->out_int = out_irqs;
Kojto 71:53949e6131f6 474
Kojto 71:53949e6131f6 475 if (out_irqs & 1) {
Kojto 71:53949e6131f6 476 EP0out();
Kojto 71:53949e6131f6 477 }
Kojto 71:53949e6131f6 478
Kojto 71:53949e6131f6 479 for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) {
Kojto 71:53949e6131f6 480 uint32_t irq_mask = (1 << epnum);
Kojto 71:53949e6131f6 481 if (out_irqs & irq_mask) {
Kojto 71:53949e6131f6 482 uint8_t endpoint = (epnum << 1) | DIR_OUT;
Kojto 71:53949e6131f6 483 (instance->*(epCallback[endpoint]))();
Kojto 71:53949e6131f6 484 }
Kojto 71:53949e6131f6 485 }
Kojto 71:53949e6131f6 486 }
Kojto 71:53949e6131f6 487 }
Kojto 71:53949e6131f6 488
Kojto 71:53949e6131f6 489 #endif