A copy of the mbed USBDevice with USBSerial library

Dependents:   STM32L0_LoRa Smartage STM32L0_LoRa Turtle_RadioShuttle

Committer:
Helmut Tschemernjak
Date:
Thu Jan 31 20:56:55 2019 +0100
Revision:
7:8a5cc0d9bfa2
Parent:
0:a3ea811f80f2
fixed compiler warnings

Who changed what in which revision?

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