USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

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