Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /* CMSIS-DAP Interface Firmware
Pawel Zarembski 0:01f31e923fe2 2 * Copyright (c) 2009-2013 ARM Limited
Pawel Zarembski 0:01f31e923fe2 3 *
Pawel Zarembski 0:01f31e923fe2 4 * Licensed under the Apache License, Version 2.0 (the "License");
Pawel Zarembski 0:01f31e923fe2 5 * you may not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 6 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 7 *
Pawel Zarembski 0:01f31e923fe2 8 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 9 *
Pawel Zarembski 0:01f31e923fe2 10 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 11 * distributed under the License is distributed on an "AS IS" BASIS,
Pawel Zarembski 0:01f31e923fe2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 13 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 14 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 15 */
Pawel Zarembski 0:01f31e923fe2 16
Pawel Zarembski 0:01f31e923fe2 17 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 18 #include "rl_usb.h"
Pawel Zarembski 0:01f31e923fe2 19 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 20
Pawel Zarembski 0:01f31e923fe2 21 #include "max32620.h"
Pawel Zarembski 0:01f31e923fe2 22 #include "usb_regs.h"
Pawel Zarembski 0:01f31e923fe2 23 #include "clkman_regs.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "pwrman_regs.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "tmr_regs.h"
Pawel Zarembski 0:01f31e923fe2 26
Pawel Zarembski 0:01f31e923fe2 27 #define __NO_USB_LIB_C
Pawel Zarembski 0:01f31e923fe2 28 #include "usb_config.c"
Pawel Zarembski 0:01f31e923fe2 29
Pawel Zarembski 0:01f31e923fe2 30 #define EPNUM_MASK (~USB_ENDPOINT_DIRECTION_MASK)
Pawel Zarembski 0:01f31e923fe2 31
Pawel Zarembski 0:01f31e923fe2 32 #define INIT_INTS (MXC_F_USB_DEV_INTEN_BRST | MXC_F_USB_DEV_INTFL_BRST_DN | MXC_F_USB_DEV_INTEN_VBUS | MXC_F_USB_DEV_INTFL_NO_VBUS)
Pawel Zarembski 0:01f31e923fe2 33 #define CONNECT_INTS (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)
Pawel Zarembski 0:01f31e923fe2 34
Pawel Zarembski 0:01f31e923fe2 35 typedef struct {
Pawel Zarembski 0:01f31e923fe2 36 volatile uint32_t buf0_desc;
Pawel Zarembski 0:01f31e923fe2 37 volatile uint32_t buf0_address;
Pawel Zarembski 0:01f31e923fe2 38 volatile uint32_t buf1_desc;
Pawel Zarembski 0:01f31e923fe2 39 volatile uint32_t buf1_address;
Pawel Zarembski 0:01f31e923fe2 40 } ep_buffer_t;
Pawel Zarembski 0:01f31e923fe2 41
Pawel Zarembski 0:01f31e923fe2 42 typedef struct {
Pawel Zarembski 0:01f31e923fe2 43 ep_buffer_t out_buffer;
Pawel Zarembski 0:01f31e923fe2 44 ep_buffer_t in_buffer;
Pawel Zarembski 0:01f31e923fe2 45 } ep0_buffer_t;
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 typedef struct {
Pawel Zarembski 0:01f31e923fe2 48 ep0_buffer_t ep0;
Pawel Zarembski 0:01f31e923fe2 49 ep_buffer_t ep[MXC_USB_NUM_EP - 1];
Pawel Zarembski 0:01f31e923fe2 50 } ep_buffer_descriptor_t;
Pawel Zarembski 0:01f31e923fe2 51
Pawel Zarembski 0:01f31e923fe2 52 typedef struct {
Pawel Zarembski 0:01f31e923fe2 53 U8 type;
Pawel Zarembski 0:01f31e923fe2 54 U16 len;
Pawel Zarembski 0:01f31e923fe2 55 } ep_info_t;
Pawel Zarembski 0:01f31e923fe2 56
Pawel Zarembski 0:01f31e923fe2 57 /* static storage for endpoint buffer descriptor table, must be 512 byte aligned for DMA */
Pawel Zarembski 0:01f31e923fe2 58 __attribute__ ((aligned (512)))
Pawel Zarembski 0:01f31e923fe2 59 ep_buffer_descriptor_t ep_buffer_descriptor;
Pawel Zarembski 0:01f31e923fe2 60
Pawel Zarembski 0:01f31e923fe2 61 static uint32_t ep_buffer[MXC_USB_NUM_EP][MXC_USB_MAX_PACKET / sizeof(uint32_t)];
Pawel Zarembski 0:01f31e923fe2 62 static ep_info_t ep_info[MXC_USB_NUM_EP];
Pawel Zarembski 0:01f31e923fe2 63 static volatile int suspended;
Pawel Zarembski 0:01f31e923fe2 64 static volatile int setup_waiting;
Pawel Zarembski 0:01f31e923fe2 65 static volatile int ep0_expect_zlp;
Pawel Zarembski 0:01f31e923fe2 66
Pawel Zarembski 0:01f31e923fe2 67 #if CDC_ENDPOINT
Pawel Zarembski 0:01f31e923fe2 68 /* CDC-ACM class processes FIFOs in the SOF interrupt. The USB Device interface
Pawel Zarembski 0:01f31e923fe2 69 * of Maxim's microcontrollers does not provide and SOF interrupt. A periodic
Pawel Zarembski 0:01f31e923fe2 70 * timer interrupt is used instead.
Pawel Zarembski 0:01f31e923fe2 71 */
Pawel Zarembski 0:01f31e923fe2 72 /******************************************************************************/
Pawel Zarembski 0:01f31e923fe2 73 void TMR0_IRQHandler(void)
Pawel Zarembski 0:01f31e923fe2 74 {
Pawel Zarembski 0:01f31e923fe2 75 MXC_TMR0->intfl = MXC_TMR0->intfl;
Pawel Zarembski 0:01f31e923fe2 76
Pawel Zarembski 0:01f31e923fe2 77 if (usbd_configured()) {
Pawel Zarembski 0:01f31e923fe2 78 USBD_CDC_ACM_SOF_Event();
Pawel Zarembski 0:01f31e923fe2 79 }
Pawel Zarembski 0:01f31e923fe2 80 }
Pawel Zarembski 0:01f31e923fe2 81 #endif
Pawel Zarembski 0:01f31e923fe2 82
Pawel Zarembski 0:01f31e923fe2 83 /******************************************************************************/
Pawel Zarembski 0:01f31e923fe2 84 static ep_buffer_t *get_desc(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 85 {
Pawel Zarembski 0:01f31e923fe2 86 ep_buffer_t *desc;
Pawel Zarembski 0:01f31e923fe2 87
Pawel Zarembski 0:01f31e923fe2 88 if (EPNum == 0x80) {
Pawel Zarembski 0:01f31e923fe2 89 desc = &ep_buffer_descriptor.ep0.in_buffer;
Pawel Zarembski 0:01f31e923fe2 90 } else if (EPNum == 0x00) {
Pawel Zarembski 0:01f31e923fe2 91 desc = &ep_buffer_descriptor.ep0.out_buffer;
Pawel Zarembski 0:01f31e923fe2 92 } else {
Pawel Zarembski 0:01f31e923fe2 93 desc = &ep_buffer_descriptor.ep[(EPNum & EPNUM_MASK) - 1];
Pawel Zarembski 0:01f31e923fe2 94 }
Pawel Zarembski 0:01f31e923fe2 95
Pawel Zarembski 0:01f31e923fe2 96 return desc;
Pawel Zarembski 0:01f31e923fe2 97 }
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99 /*
Pawel Zarembski 0:01f31e923fe2 100 * USB Device Interrupt enable
Pawel Zarembski 0:01f31e923fe2 101 * Called by USBD_Init to enable the USB Interrupt
Pawel Zarembski 0:01f31e923fe2 102 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 103 */
Pawel Zarembski 0:01f31e923fe2 104
Pawel Zarembski 0:01f31e923fe2 105 void USBD_IntrEna(void)
Pawel Zarembski 0:01f31e923fe2 106 {
Pawel Zarembski 0:01f31e923fe2 107 NVIC_EnableIRQ(USB_IRQn); /* Enable OTG interrupt */
Pawel Zarembski 0:01f31e923fe2 108 }
Pawel Zarembski 0:01f31e923fe2 109
Pawel Zarembski 0:01f31e923fe2 110 /******************************************************************************/
Pawel Zarembski 0:01f31e923fe2 111 /*
Pawel Zarembski 0:01f31e923fe2 112 * Usb interrupt enable/disable
Pawel Zarembski 0:01f31e923fe2 113 * Parameters: ena: enable/disable
Pawel Zarembski 0:01f31e923fe2 114 * 0: disable interrupt
Pawel Zarembski 0:01f31e923fe2 115 * 1: enable interrupt
Pawel Zarembski 0:01f31e923fe2 116 */
Pawel Zarembski 0:01f31e923fe2 117 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 118 void __svc(1) USBD_Intr (int ena);
Pawel Zarembski 0:01f31e923fe2 119 void __SVC_1 (int ena)
Pawel Zarembski 0:01f31e923fe2 120 {
Pawel Zarembski 0:01f31e923fe2 121 if (ena) {
Pawel Zarembski 0:01f31e923fe2 122 NVIC_EnableIRQ(USB_IRQn); /* Enable USB interrupt */
Pawel Zarembski 0:01f31e923fe2 123 } else {
Pawel Zarembski 0:01f31e923fe2 124 NVIC_DisableIRQ(USB_IRQn); /* Disable USB interrupt */
Pawel Zarembski 0:01f31e923fe2 125 }
Pawel Zarembski 0:01f31e923fe2 126 }
Pawel Zarembski 0:01f31e923fe2 127 #endif
Pawel Zarembski 0:01f31e923fe2 128
Pawel Zarembski 0:01f31e923fe2 129 /******************************************************************************/
Pawel Zarembski 0:01f31e923fe2 130 static void reset_state(void)
Pawel Zarembski 0:01f31e923fe2 131 {
Pawel Zarembski 0:01f31e923fe2 132 unsigned int ep;
Pawel Zarembski 0:01f31e923fe2 133
Pawel Zarembski 0:01f31e923fe2 134 suspended = 0;
Pawel Zarembski 0:01f31e923fe2 135 setup_waiting = 0;
Pawel Zarembski 0:01f31e923fe2 136 ep0_expect_zlp = 0;
Pawel Zarembski 0:01f31e923fe2 137 memset(ep_info, 0, sizeof(ep_info));
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 MXC_USB->ep[0] |= (MXC_S_USB_EP_DIR_CONTROL | MXC_F_USB_EP_INT_EN | MXC_F_USB_EP_DT);
Pawel Zarembski 0:01f31e923fe2 140 for (ep = 1; ep < MXC_USB_NUM_EP; ep++) {
Pawel Zarembski 0:01f31e923fe2 141 MXC_USB->ep[ep] = MXC_F_USB_EP_DT;
Pawel Zarembski 0:01f31e923fe2 142 }
Pawel Zarembski 0:01f31e923fe2 143 }
Pawel Zarembski 0:01f31e923fe2 144
Pawel Zarembski 0:01f31e923fe2 145 /*
Pawel Zarembski 0:01f31e923fe2 146 * USB Device Initialize Function
Pawel Zarembski 0:01f31e923fe2 147 * Called by the User to initialize USB Device
Pawel Zarembski 0:01f31e923fe2 148 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 149 */
Pawel Zarembski 0:01f31e923fe2 150 void USBD_Init (void)
Pawel Zarembski 0:01f31e923fe2 151 {
Pawel Zarembski 0:01f31e923fe2 152 uint32_t reg;
Pawel Zarembski 0:01f31e923fe2 153
Pawel Zarembski 0:01f31e923fe2 154 /* Enable USB power domain */
Pawel Zarembski 0:01f31e923fe2 155 MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED;
Pawel Zarembski 0:01f31e923fe2 156 /* Setup the USB clocking, select */
Pawel Zarembski 0:01f31e923fe2 157 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE;
Pawel Zarembski 0:01f31e923fe2 158 /* Force USB clock gater */
Pawel Zarembski 0:01f31e923fe2 159 reg = MXC_CLKMAN->clk_gate_ctrl0;
Pawel Zarembski 0:01f31e923fe2 160 reg &= ~MXC_F_CLKMAN_CLK_GATE_CTRL0_USB_CLK_GATER;
Pawel Zarembski 0:01f31e923fe2 161 reg |= (0x2 << MXC_F_CLKMAN_CLK_GATE_CTRL0_USB_CLK_GATER_POS);
Pawel Zarembski 0:01f31e923fe2 162 MXC_CLKMAN->clk_gate_ctrl0 = reg;
Pawel Zarembski 0:01f31e923fe2 163
Pawel Zarembski 0:01f31e923fe2 164 MXC_USB->cn = 0;
Pawel Zarembski 0:01f31e923fe2 165 MXC_USB->cn = MXC_F_USB_CN_USB_EN;
Pawel Zarembski 0:01f31e923fe2 166 MXC_USB->dev_inten = 0;
Pawel Zarembski 0:01f31e923fe2 167 MXC_USB->dev_intfl = 0xFFFF; // clear interrupts
Pawel Zarembski 0:01f31e923fe2 168 MXC_USB->dev_cn = 0;
Pawel Zarembski 0:01f31e923fe2 169 MXC_USB->dev_cn |= MXC_F_USB_DEV_CN_URST;
Pawel Zarembski 0:01f31e923fe2 170 MXC_USB->dev_cn = 0;
Pawel Zarembski 0:01f31e923fe2 171
Pawel Zarembski 0:01f31e923fe2 172 reset_state();
Pawel Zarembski 0:01f31e923fe2 173
Pawel Zarembski 0:01f31e923fe2 174 /* set the descriptor location */
Pawel Zarembski 0:01f31e923fe2 175 MXC_USB->ep_base = (uint32_t)&ep_buffer_descriptor;
Pawel Zarembski 0:01f31e923fe2 176
Pawel Zarembski 0:01f31e923fe2 177 /* enable some interrupts */
Pawel Zarembski 0:01f31e923fe2 178 MXC_USB->dev_inten = INIT_INTS;
Pawel Zarembski 0:01f31e923fe2 179 NVIC_EnableIRQ(USB_IRQn);
Pawel Zarembski 0:01f31e923fe2 180 }
Pawel Zarembski 0:01f31e923fe2 181
Pawel Zarembski 0:01f31e923fe2 182 /*
Pawel Zarembski 0:01f31e923fe2 183 * USB Device Connect Function
Pawel Zarembski 0:01f31e923fe2 184 * Called by the User to Connect/Disconnect USB Device
Pawel Zarembski 0:01f31e923fe2 185 * Parameters: con: Connect/Disconnect
Pawel Zarembski 0:01f31e923fe2 186 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 187 */
Pawel Zarembski 0:01f31e923fe2 188 void USBD_Connect (BOOL con)
Pawel Zarembski 0:01f31e923fe2 189 {
Pawel Zarembski 0:01f31e923fe2 190 if (con) {
Pawel Zarembski 0:01f31e923fe2 191 MXC_USB->dev_intfl = 0xFFFF; // clear interrupts
Pawel Zarembski 0:01f31e923fe2 192 MXC_USB->dev_inten |= CONNECT_INTS;
Pawel Zarembski 0:01f31e923fe2 193 MXC_USB->ep[0] |= MXC_F_USB_EP_INT_EN;
Pawel Zarembski 0:01f31e923fe2 194 MXC_USB->dev_cn |= (MXC_F_USB_DEV_CN_CONNECT | MXC_F_USB_DEV_CN_FIFO_MODE);
Pawel Zarembski 0:01f31e923fe2 195 } else {
Pawel Zarembski 0:01f31e923fe2 196 MXC_USB->dev_inten &= ~CONNECT_INTS;
Pawel Zarembski 0:01f31e923fe2 197 MXC_USB->ep[0] &= ~MXC_F_USB_EP_INT_EN;
Pawel Zarembski 0:01f31e923fe2 198 MXC_USB->dev_cn &= ~MXC_F_USB_DEV_CN_CONNECT;
Pawel Zarembski 0:01f31e923fe2 199 }
Pawel Zarembski 0:01f31e923fe2 200 }
Pawel Zarembski 0:01f31e923fe2 201
Pawel Zarembski 0:01f31e923fe2 202 /*
Pawel Zarembski 0:01f31e923fe2 203 * USB Device Remote Wakeup Configuration Function
Pawel Zarembski 0:01f31e923fe2 204 * Parameters: cfg: Device Enable/Disable
Pawel Zarembski 0:01f31e923fe2 205 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 206 */
Pawel Zarembski 0:01f31e923fe2 207 void USBD_WakeUpCfg (BOOL cfg)
Pawel Zarembski 0:01f31e923fe2 208 {
Pawel Zarembski 0:01f31e923fe2 209 }
Pawel Zarembski 0:01f31e923fe2 210
Pawel Zarembski 0:01f31e923fe2 211 /*
Pawel Zarembski 0:01f31e923fe2 212 * USB Device Set Address Function
Pawel Zarembski 0:01f31e923fe2 213 * Parameters: adr: USB Device Address
Pawel Zarembski 0:01f31e923fe2 214 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 215 */
Pawel Zarembski 0:01f31e923fe2 216 void USBD_SetAddress (U32 adr, U32 setup)
Pawel Zarembski 0:01f31e923fe2 217 {
Pawel Zarembski 0:01f31e923fe2 218 /* Performed by Hardware */
Pawel Zarembski 0:01f31e923fe2 219 }
Pawel Zarembski 0:01f31e923fe2 220
Pawel Zarembski 0:01f31e923fe2 221 /*
Pawel Zarembski 0:01f31e923fe2 222 * USB Device Configure Function
Pawel Zarembski 0:01f31e923fe2 223 * Parameters: cfg: Device Configure/Deconfigure
Pawel Zarembski 0:01f31e923fe2 224 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 225 */
Pawel Zarembski 0:01f31e923fe2 226 void USBD_Configure (BOOL cfg)
Pawel Zarembski 0:01f31e923fe2 227 {
Pawel Zarembski 0:01f31e923fe2 228 #if CDC_ENDPOINT
Pawel Zarembski 0:01f31e923fe2 229 /* CDC-ACM class processes FIFOs in the SOF interrupt. The USB Device interface
Pawel Zarembski 0:01f31e923fe2 230 * of Maxim's microcontrollers does not provide and SOF interrupt. A periodic
Pawel Zarembski 0:01f31e923fe2 231 * timer interrupt is used instead.
Pawel Zarembski 0:01f31e923fe2 232 */
Pawel Zarembski 0:01f31e923fe2 233
Pawel Zarembski 0:01f31e923fe2 234 #define SOF_INT_US 1000
Pawel Zarembski 0:01f31e923fe2 235
Pawel Zarembski 0:01f31e923fe2 236 if (cfg) {
Pawel Zarembski 0:01f31e923fe2 237 // Setup timer interrupt for SOF
Pawel Zarembski 0:01f31e923fe2 238 MXC_TMR0->ctrl = MXC_S_TMR_CTRL_MODE_CONTINUOUS;
Pawel Zarembski 0:01f31e923fe2 239 MXC_TMR0->count32 = 0;
Pawel Zarembski 0:01f31e923fe2 240 MXC_TMR0->term_cnt32 = (SystemCoreClock / 1000000) * SOF_INT_US;
Pawel Zarembski 0:01f31e923fe2 241
Pawel Zarembski 0:01f31e923fe2 242 // Enable the interrupt
Pawel Zarembski 0:01f31e923fe2 243 MXC_TMR0->intfl = MXC_TMR0->intfl;
Pawel Zarembski 0:01f31e923fe2 244 NVIC_EnableIRQ(TMR0_0_IRQn);
Pawel Zarembski 0:01f31e923fe2 245 MXC_TMR0->inten = MXC_F_TMR_INTEN_TIMER0;
Pawel Zarembski 0:01f31e923fe2 246
Pawel Zarembski 0:01f31e923fe2 247 // Start the timer
Pawel Zarembski 0:01f31e923fe2 248 MXC_TMR0->ctrl |= MXC_F_TMR_CTRL_ENABLE0;
Pawel Zarembski 0:01f31e923fe2 249
Pawel Zarembski 0:01f31e923fe2 250 } else {
Pawel Zarembski 0:01f31e923fe2 251 // Disable tmr
Pawel Zarembski 0:01f31e923fe2 252 MXC_TMR0->ctrl &= ~(MXC_F_TMR_CTRL_ENABLE0);
Pawel Zarembski 0:01f31e923fe2 253 }
Pawel Zarembski 0:01f31e923fe2 254 #endif
Pawel Zarembski 0:01f31e923fe2 255 }
Pawel Zarembski 0:01f31e923fe2 256
Pawel Zarembski 0:01f31e923fe2 257 /*
Pawel Zarembski 0:01f31e923fe2 258 * Configure USB Device Endpoint according to Descriptor
Pawel Zarembski 0:01f31e923fe2 259 * Parameters: pEPD: Pointer to Device Endpoint Descriptor
Pawel Zarembski 0:01f31e923fe2 260 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 261 */
Pawel Zarembski 0:01f31e923fe2 262 void USBD_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD)
Pawel Zarembski 0:01f31e923fe2 263 {
Pawel Zarembski 0:01f31e923fe2 264 U32 EPNum;
Pawel Zarembski 0:01f31e923fe2 265
Pawel Zarembski 0:01f31e923fe2 266 EPNum = pEPD->bEndpointAddress & EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 267
Pawel Zarembski 0:01f31e923fe2 268 if (EPNum < MXC_USB_NUM_EP) {
Pawel Zarembski 0:01f31e923fe2 269
Pawel Zarembski 0:01f31e923fe2 270 // Clear existing configurations
Pawel Zarembski 0:01f31e923fe2 271 MXC_USB->ep[EPNum] = MXC_F_USB_EP_DT;
Pawel Zarembski 0:01f31e923fe2 272
Pawel Zarembski 0:01f31e923fe2 273 if (pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) {
Pawel Zarembski 0:01f31e923fe2 274 ep_info[EPNum].type = MXC_S_USB_EP_DIR_IN;
Pawel Zarembski 0:01f31e923fe2 275 } else {
Pawel Zarembski 0:01f31e923fe2 276 ep_info[EPNum].type = MXC_S_USB_EP_DIR_OUT;
Pawel Zarembski 0:01f31e923fe2 277 }
Pawel Zarembski 0:01f31e923fe2 278
Pawel Zarembski 0:01f31e923fe2 279 ep_info[EPNum].len = pEPD->wMaxPacketSize;
Pawel Zarembski 0:01f31e923fe2 280 }
Pawel Zarembski 0:01f31e923fe2 281 }
Pawel Zarembski 0:01f31e923fe2 282
Pawel Zarembski 0:01f31e923fe2 283 /*
Pawel Zarembski 0:01f31e923fe2 284 * Set Direction for USB Device Control Endpoint
Pawel Zarembski 0:01f31e923fe2 285 * Parameters: dir: Out (dir == 0), In (dir <> 0)
Pawel Zarembski 0:01f31e923fe2 286 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 287 */
Pawel Zarembski 0:01f31e923fe2 288 void USBD_DirCtrlEP (U32 dir)
Pawel Zarembski 0:01f31e923fe2 289 {
Pawel Zarembski 0:01f31e923fe2 290 /* Not needed */
Pawel Zarembski 0:01f31e923fe2 291 }
Pawel Zarembski 0:01f31e923fe2 292
Pawel Zarembski 0:01f31e923fe2 293 /*
Pawel Zarembski 0:01f31e923fe2 294 * Enable USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 295 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 296 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 297 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 298 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 299 */
Pawel Zarembski 0:01f31e923fe2 300 void USBD_EnableEP (U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 301 {
Pawel Zarembski 0:01f31e923fe2 302 ep_buffer_t *desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 303
Pawel Zarembski 0:01f31e923fe2 304 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 305 MXC_USB->ep[EPNum] |= (MXC_F_USB_EP_INT_EN | ep_info[EPNum].type | MXC_F_USB_EP_DT);
Pawel Zarembski 0:01f31e923fe2 306
Pawel Zarembski 0:01f31e923fe2 307 if (ep_info[EPNum].type == MXC_S_USB_EP_DIR_OUT) {
Pawel Zarembski 0:01f31e923fe2 308 // This is an OUT endpoint. Go ahead and register a request.
Pawel Zarembski 0:01f31e923fe2 309 desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 310 desc->buf0_address = (uint32_t)ep_buffer[EPNum];
Pawel Zarembski 0:01f31e923fe2 311 desc->buf0_desc = sizeof(ep_buffer[EPNum]);
Pawel Zarembski 0:01f31e923fe2 312 MXC_USB->out_owner = (1 << EPNum);
Pawel Zarembski 0:01f31e923fe2 313 }
Pawel Zarembski 0:01f31e923fe2 314 }
Pawel Zarembski 0:01f31e923fe2 315
Pawel Zarembski 0:01f31e923fe2 316 /*
Pawel Zarembski 0:01f31e923fe2 317 * Disable USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 318 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 319 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 320 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 321 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 322 */
Pawel Zarembski 0:01f31e923fe2 323 void USBD_DisableEP (U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 324 {
Pawel Zarembski 0:01f31e923fe2 325 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 326 MXC_USB->ep[EPNum] = 0;
Pawel Zarembski 0:01f31e923fe2 327 }
Pawel Zarembski 0:01f31e923fe2 328
Pawel Zarembski 0:01f31e923fe2 329 /*
Pawel Zarembski 0:01f31e923fe2 330 * Reset USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 331 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 332 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 333 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 334 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 335 */
Pawel Zarembski 0:01f31e923fe2 336 void USBD_ResetEP (U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 337 {
Pawel Zarembski 0:01f31e923fe2 338 ep_buffer_t *desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 339
Pawel Zarembski 0:01f31e923fe2 340 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 341 MXC_USB->ep[EPNum] |= MXC_F_USB_EP_DT;
Pawel Zarembski 0:01f31e923fe2 342
Pawel Zarembski 0:01f31e923fe2 343 if (ep_info[EPNum].type == MXC_S_USB_EP_DIR_OUT) {
Pawel Zarembski 0:01f31e923fe2 344 // This is an OUT endpoint. Go ahead and register a request.
Pawel Zarembski 0:01f31e923fe2 345 desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 346 desc->buf0_address = (uint32_t)ep_buffer[EPNum];
Pawel Zarembski 0:01f31e923fe2 347 desc->buf0_desc = sizeof(ep_buffer[EPNum]);
Pawel Zarembski 0:01f31e923fe2 348 MXC_USB->out_owner = (1 << EPNum);
Pawel Zarembski 0:01f31e923fe2 349 }
Pawel Zarembski 0:01f31e923fe2 350 }
Pawel Zarembski 0:01f31e923fe2 351
Pawel Zarembski 0:01f31e923fe2 352 /*
Pawel Zarembski 0:01f31e923fe2 353 * Set Stall for USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 354 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 355 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 356 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 357 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 358 */
Pawel Zarembski 0:01f31e923fe2 359 void USBD_SetStallEP (U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 360 {
Pawel Zarembski 0:01f31e923fe2 361 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 362
Pawel Zarembski 0:01f31e923fe2 363 if (EPNum == 0) {
Pawel Zarembski 0:01f31e923fe2 364 MXC_USB->ep[0] |= (MXC_F_USB_EP_ST_STALL | MXC_F_USB_EP_STALL);
Pawel Zarembski 0:01f31e923fe2 365 } else {
Pawel Zarembski 0:01f31e923fe2 366 MXC_USB->ep[EPNum] |= MXC_F_USB_EP_STALL;
Pawel Zarembski 0:01f31e923fe2 367 }
Pawel Zarembski 0:01f31e923fe2 368 }
Pawel Zarembski 0:01f31e923fe2 369
Pawel Zarembski 0:01f31e923fe2 370 /*
Pawel Zarembski 0:01f31e923fe2 371 * Clear Stall for USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 372 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 373 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 374 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 375 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 376 */
Pawel Zarembski 0:01f31e923fe2 377 void USBD_ClrStallEP (U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 378 {
Pawel Zarembski 0:01f31e923fe2 379 USBD_ResetEP(EPNum);
Pawel Zarembski 0:01f31e923fe2 380 MXC_USB->ep[EPNum & EPNUM_MASK] &= ~MXC_F_USB_EP_STALL;
Pawel Zarembski 0:01f31e923fe2 381 }
Pawel Zarembski 0:01f31e923fe2 382
Pawel Zarembski 0:01f31e923fe2 383 /*
Pawel Zarembski 0:01f31e923fe2 384 * Read USB Device Endpoint Data
Pawel Zarembski 0:01f31e923fe2 385 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 386 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 387 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 388 * pData: Pointer to Data Buffer
Pawel Zarembski 0:01f31e923fe2 389 * Return Value: Number of bytes read
Pawel Zarembski 0:01f31e923fe2 390 */
Pawel Zarembski 0:01f31e923fe2 391 U32 USBD_ReadEP (U32 EPNum, U8 *pData, U32 size)
Pawel Zarembski 0:01f31e923fe2 392 {
Pawel Zarembski 0:01f31e923fe2 393 U32 cnt;
Pawel Zarembski 0:01f31e923fe2 394 ep_buffer_t *desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 395 USB_SETUP_PACKET *sup;
Pawel Zarembski 0:01f31e923fe2 396
Pawel Zarembski 0:01f31e923fe2 397 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 398
Pawel Zarembski 0:01f31e923fe2 399 if ((EPNum == 0) && setup_waiting) {
Pawel Zarembski 0:01f31e923fe2 400 cnt = USBD_MAX_PACKET0;
Pawel Zarembski 0:01f31e923fe2 401
Pawel Zarembski 0:01f31e923fe2 402 if (size < cnt) {
Pawel Zarembski 0:01f31e923fe2 403 cnt = size;
Pawel Zarembski 0:01f31e923fe2 404 }
Pawel Zarembski 0:01f31e923fe2 405 setup_waiting = 0;
Pawel Zarembski 0:01f31e923fe2 406 memcpy(pData, (void*)&MXC_USB->setup0, cnt);
Pawel Zarembski 0:01f31e923fe2 407 sup = (USB_SETUP_PACKET*)pData;
Pawel Zarembski 0:01f31e923fe2 408
Pawel Zarembski 0:01f31e923fe2 409 if ( (sup->bmRequestType.Dir == REQUEST_HOST_TO_DEVICE) && (sup->wLength > 0) ) {
Pawel Zarembski 0:01f31e923fe2 410 // There is an OUT stage for this setup packet. Register a request.
Pawel Zarembski 0:01f31e923fe2 411 if (!(MXC_USB->out_owner & 1)) {
Pawel Zarembski 0:01f31e923fe2 412 desc = &ep_buffer_descriptor.ep0.out_buffer;
Pawel Zarembski 0:01f31e923fe2 413 desc->buf0_address = (uint32_t)ep_buffer[0];
Pawel Zarembski 0:01f31e923fe2 414 desc->buf0_desc = sup->wLength;
Pawel Zarembski 0:01f31e923fe2 415 MXC_USB->out_owner = 1;
Pawel Zarembski 0:01f31e923fe2 416 }
Pawel Zarembski 0:01f31e923fe2 417 }
Pawel Zarembski 0:01f31e923fe2 418 } else {
Pawel Zarembski 0:01f31e923fe2 419 cnt = desc->buf0_desc;
Pawel Zarembski 0:01f31e923fe2 420
Pawel Zarembski 0:01f31e923fe2 421 if (size < cnt) {
Pawel Zarembski 0:01f31e923fe2 422 cnt = size;
Pawel Zarembski 0:01f31e923fe2 423 }
Pawel Zarembski 0:01f31e923fe2 424 memcpy(pData, ep_buffer[EPNum], cnt);
Pawel Zarembski 0:01f31e923fe2 425
Pawel Zarembski 0:01f31e923fe2 426 // Register the next request.
Pawel Zarembski 0:01f31e923fe2 427 desc->buf0_address = (uint32_t)ep_buffer[EPNum];
Pawel Zarembski 0:01f31e923fe2 428 desc->buf0_desc = sizeof(ep_buffer[EPNum]);
Pawel Zarembski 0:01f31e923fe2 429 MXC_USB->out_owner = (1 << EPNum);
Pawel Zarembski 0:01f31e923fe2 430 }
Pawel Zarembski 0:01f31e923fe2 431
Pawel Zarembski 0:01f31e923fe2 432 return cnt;
Pawel Zarembski 0:01f31e923fe2 433 }
Pawel Zarembski 0:01f31e923fe2 434
Pawel Zarembski 0:01f31e923fe2 435 /*
Pawel Zarembski 0:01f31e923fe2 436 * Write USB Device Endpoint Data
Pawel Zarembski 0:01f31e923fe2 437 * Parameters: EPNum: Endpoint Number
Pawel Zarembski 0:01f31e923fe2 438 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 439 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 440 * pData: Pointer to Data Buffer
Pawel Zarembski 0:01f31e923fe2 441 * cnt: Number of bytes to write
Pawel Zarembski 0:01f31e923fe2 442 * Return Value: Number of bytes written
Pawel Zarembski 0:01f31e923fe2 443 */
Pawel Zarembski 0:01f31e923fe2 444 U32 USBD_WriteEP (U32 EPNum, U8 *pData, U32 cnt)
Pawel Zarembski 0:01f31e923fe2 445 {
Pawel Zarembski 0:01f31e923fe2 446 ep_buffer_t *desc = get_desc(EPNum);
Pawel Zarembski 0:01f31e923fe2 447 uint32_t mask;
Pawel Zarembski 0:01f31e923fe2 448
Pawel Zarembski 0:01f31e923fe2 449 EPNum &= EPNUM_MASK;
Pawel Zarembski 0:01f31e923fe2 450 mask = (1 << EPNum);
Pawel Zarembski 0:01f31e923fe2 451
Pawel Zarembski 0:01f31e923fe2 452 if (MXC_USB->in_owner & mask) {
Pawel Zarembski 0:01f31e923fe2 453 return 0;
Pawel Zarembski 0:01f31e923fe2 454 }
Pawel Zarembski 0:01f31e923fe2 455
Pawel Zarembski 0:01f31e923fe2 456 if (EPNum == 0) {
Pawel Zarembski 0:01f31e923fe2 457 // Prepare to ACK the status stage.
Pawel Zarembski 0:01f31e923fe2 458 MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK;
Pawel Zarembski 0:01f31e923fe2 459
Pawel Zarembski 0:01f31e923fe2 460 if ((cnt == 0) && !ep0_expect_zlp) {
Pawel Zarembski 0:01f31e923fe2 461 // This is a status stage ACK. Handled in hardware.
Pawel Zarembski 0:01f31e923fe2 462 return 0;
Pawel Zarembski 0:01f31e923fe2 463 } else if (cnt == USBD_MAX_PACKET0) {
Pawel Zarembski 0:01f31e923fe2 464 ep0_expect_zlp = 1;
Pawel Zarembski 0:01f31e923fe2 465 } else {
Pawel Zarembski 0:01f31e923fe2 466 ep0_expect_zlp = 0;
Pawel Zarembski 0:01f31e923fe2 467 }
Pawel Zarembski 0:01f31e923fe2 468 }
Pawel Zarembski 0:01f31e923fe2 469
Pawel Zarembski 0:01f31e923fe2 470 if (cnt > MXC_USB_MAX_PACKET) {
Pawel Zarembski 0:01f31e923fe2 471 cnt = MXC_USB_MAX_PACKET;
Pawel Zarembski 0:01f31e923fe2 472 }
Pawel Zarembski 0:01f31e923fe2 473
Pawel Zarembski 0:01f31e923fe2 474 /* prepare data to be sent */
Pawel Zarembski 0:01f31e923fe2 475 memcpy(ep_buffer[EPNum], pData, cnt);
Pawel Zarembski 0:01f31e923fe2 476 desc->buf0_address = (uint32_t)ep_buffer[EPNum];
Pawel Zarembski 0:01f31e923fe2 477 desc->buf0_desc = cnt;
Pawel Zarembski 0:01f31e923fe2 478
Pawel Zarembski 0:01f31e923fe2 479 /* start the transaction */
Pawel Zarembski 0:01f31e923fe2 480 MXC_USB->in_owner = mask;
Pawel Zarembski 0:01f31e923fe2 481
Pawel Zarembski 0:01f31e923fe2 482 return cnt;
Pawel Zarembski 0:01f31e923fe2 483 }
Pawel Zarembski 0:01f31e923fe2 484
Pawel Zarembski 0:01f31e923fe2 485 /*
Pawel Zarembski 0:01f31e923fe2 486 * USB Device Interrupt Service Routine
Pawel Zarembski 0:01f31e923fe2 487 */
Pawel Zarembski 0:01f31e923fe2 488 void USB_IRQHandler (void)
Pawel Zarembski 0:01f31e923fe2 489 {
Pawel Zarembski 0:01f31e923fe2 490 NVIC_DisableIRQ(USB_IRQn);
Pawel Zarembski 0:01f31e923fe2 491 USBD_SignalHandler();
Pawel Zarembski 0:01f31e923fe2 492 }
Pawel Zarembski 0:01f31e923fe2 493
Pawel Zarembski 0:01f31e923fe2 494 void USBD_Handler(void)
Pawel Zarembski 0:01f31e923fe2 495 {
Pawel Zarembski 0:01f31e923fe2 496
Pawel Zarembski 0:01f31e923fe2 497 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 498 while(1) {}
Pawel Zarembski 0:01f31e923fe2 499 #else
Pawel Zarembski 0:01f31e923fe2 500
Pawel Zarembski 0:01f31e923fe2 501 #endif
Pawel Zarembski 0:01f31e923fe2 502
Pawel Zarembski 0:01f31e923fe2 503 uint32_t irq_flags;
Pawel Zarembski 0:01f31e923fe2 504 unsigned int ep;
Pawel Zarembski 0:01f31e923fe2 505 uint32_t ep_int, mask;
Pawel Zarembski 0:01f31e923fe2 506
Pawel Zarembski 0:01f31e923fe2 507 // Read and clear interrupts
Pawel Zarembski 0:01f31e923fe2 508 irq_flags = MXC_USB->dev_intfl;
Pawel Zarembski 0:01f31e923fe2 509 MXC_USB->dev_intfl = irq_flags;
Pawel Zarembski 0:01f31e923fe2 510
Pawel Zarembski 0:01f31e923fe2 511 /* reset interrupt */
Pawel Zarembski 0:01f31e923fe2 512 if (irq_flags & MXC_F_USB_DEV_INTFL_BRST) {
Pawel Zarembski 0:01f31e923fe2 513 if (suspended) {
Pawel Zarembski 0:01f31e923fe2 514 suspended = 0;
Pawel Zarembski 0:01f31e923fe2 515 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 516 if (USBD_RTX_DevTask) { isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); }
Pawel Zarembski 0:01f31e923fe2 517 #else
Pawel Zarembski 0:01f31e923fe2 518 if (USBD_P_Resume_Event) { USBD_P_Resume_Event(); }
Pawel Zarembski 0:01f31e923fe2 519 #endif
Pawel Zarembski 0:01f31e923fe2 520 }
Pawel Zarembski 0:01f31e923fe2 521
Pawel Zarembski 0:01f31e923fe2 522 reset_state();
Pawel Zarembski 0:01f31e923fe2 523 usbd_reset_core();
Pawel Zarembski 0:01f31e923fe2 524
Pawel Zarembski 0:01f31e923fe2 525 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 526 if (USBD_RTX_DevTask) { isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); }
Pawel Zarembski 0:01f31e923fe2 527 #else
Pawel Zarembski 0:01f31e923fe2 528 if (USBD_P_Reset_Event) { USBD_P_Reset_Event(); }
Pawel Zarembski 0:01f31e923fe2 529 #endif
Pawel Zarembski 0:01f31e923fe2 530
Pawel Zarembski 0:01f31e923fe2 531 }
Pawel Zarembski 0:01f31e923fe2 532
Pawel Zarembski 0:01f31e923fe2 533 /* reset done interrupt */
Pawel Zarembski 0:01f31e923fe2 534 if (irq_flags & MXC_F_USB_DEV_INTFL_BRST_DN) {
Pawel Zarembski 0:01f31e923fe2 535 reset_state();
Pawel Zarembski 0:01f31e923fe2 536 }
Pawel Zarembski 0:01f31e923fe2 537
Pawel Zarembski 0:01f31e923fe2 538 /* suspend interrupt */
Pawel Zarembski 0:01f31e923fe2 539 if (irq_flags & MXC_F_USB_DEV_INTFL_SUSP) {
Pawel Zarembski 0:01f31e923fe2 540 suspended = 1;
Pawel Zarembski 0:01f31e923fe2 541 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 542 if (USBD_RTX_DevTask) { isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); }
Pawel Zarembski 0:01f31e923fe2 543 #else
Pawel Zarembski 0:01f31e923fe2 544 if (USBD_P_Suspend_Event) { USBD_P_Suspend_Event(); }
Pawel Zarembski 0:01f31e923fe2 545 #endif
Pawel Zarembski 0:01f31e923fe2 546 }
Pawel Zarembski 0:01f31e923fe2 547
Pawel Zarembski 0:01f31e923fe2 548 if (irq_flags & MXC_F_USB_DEV_INTFL_VBUS) {
Pawel Zarembski 0:01f31e923fe2 549 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 550 if (USBD_RTX_DevTask) { isr_evt_set(USBD_EVT_POWER_ON, USBD_RTX_DevTask); }
Pawel Zarembski 0:01f31e923fe2 551 #else
Pawel Zarembski 0:01f31e923fe2 552 if (USBD_P_Power_Event) { USBD_P_Power_Event(1); }
Pawel Zarembski 0:01f31e923fe2 553 #endif
Pawel Zarembski 0:01f31e923fe2 554 }
Pawel Zarembski 0:01f31e923fe2 555
Pawel Zarembski 0:01f31e923fe2 556 if (irq_flags & MXC_F_USB_DEV_INTFL_NO_VBUS) {
Pawel Zarembski 0:01f31e923fe2 557 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 558 if (USBD_RTX_DevTask) { isr_evt_set(USBD_EVT_POWER_OFF, USBD_RTX_DevTask); }
Pawel Zarembski 0:01f31e923fe2 559 #else
Pawel Zarembski 0:01f31e923fe2 560 if (USBD_P_Power_Event) { USBD_P_Power_Event(0); }
Pawel Zarembski 0:01f31e923fe2 561 #endif
Pawel Zarembski 0:01f31e923fe2 562 }
Pawel Zarembski 0:01f31e923fe2 563
Pawel Zarembski 0:01f31e923fe2 564 if (irq_flags & MXC_F_USB_DEV_INTFL_SETUP) {
Pawel Zarembski 0:01f31e923fe2 565 setup_waiting = 1;
Pawel Zarembski 0:01f31e923fe2 566 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 567 if (USBD_RTX_EPTask[0]) { isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[0]); }
Pawel Zarembski 0:01f31e923fe2 568 #else
Pawel Zarembski 0:01f31e923fe2 569 if (USBD_P_EP[0]) { USBD_P_EP[0](USBD_EVT_SETUP); }
Pawel Zarembski 0:01f31e923fe2 570 #endif
Pawel Zarembski 0:01f31e923fe2 571 }
Pawel Zarembski 0:01f31e923fe2 572
Pawel Zarembski 0:01f31e923fe2 573 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_IN) {
Pawel Zarembski 0:01f31e923fe2 574
Pawel Zarembski 0:01f31e923fe2 575 // Read and clear endpoint interrupts
Pawel Zarembski 0:01f31e923fe2 576 ep_int = MXC_USB->in_int;
Pawel Zarembski 0:01f31e923fe2 577 MXC_USB->in_int = ep_int;
Pawel Zarembski 0:01f31e923fe2 578
Pawel Zarembski 0:01f31e923fe2 579 mask = 1;
Pawel Zarembski 0:01f31e923fe2 580 for (ep = 0; ep < MXC_USB_NUM_EP; ep++) {
Pawel Zarembski 0:01f31e923fe2 581 if (ep_int & mask) {
Pawel Zarembski 0:01f31e923fe2 582 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 583 if (USBD_RTX_EPTask[ep]) { isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[ep]); }
Pawel Zarembski 0:01f31e923fe2 584 #else
Pawel Zarembski 0:01f31e923fe2 585 if (USBD_P_EP[ep]) { USBD_P_EP[ep](USBD_EVT_IN); }
Pawel Zarembski 0:01f31e923fe2 586 #endif
Pawel Zarembski 0:01f31e923fe2 587 }
Pawel Zarembski 0:01f31e923fe2 588
Pawel Zarembski 0:01f31e923fe2 589 mask <<= 1;
Pawel Zarembski 0:01f31e923fe2 590 }
Pawel Zarembski 0:01f31e923fe2 591 }
Pawel Zarembski 0:01f31e923fe2 592
Pawel Zarembski 0:01f31e923fe2 593 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_OUT) {
Pawel Zarembski 0:01f31e923fe2 594
Pawel Zarembski 0:01f31e923fe2 595 // Read and clear endpoint interrupts
Pawel Zarembski 0:01f31e923fe2 596 ep_int = MXC_USB->out_int;
Pawel Zarembski 0:01f31e923fe2 597 MXC_USB->out_int = ep_int;
Pawel Zarembski 0:01f31e923fe2 598
Pawel Zarembski 0:01f31e923fe2 599 mask = 1;
Pawel Zarembski 0:01f31e923fe2 600 for (ep = 0; ep < MXC_USB_NUM_EP; ep++) {
Pawel Zarembski 0:01f31e923fe2 601 if (ep_int & mask) {
Pawel Zarembski 0:01f31e923fe2 602 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 603 if (USBD_RTX_EPTask[ep]) { isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[ep]); }
Pawel Zarembski 0:01f31e923fe2 604 #else
Pawel Zarembski 0:01f31e923fe2 605 if (USBD_P_EP[ep]) { USBD_P_EP[ep](USBD_EVT_OUT); }
Pawel Zarembski 0:01f31e923fe2 606 #endif
Pawel Zarembski 0:01f31e923fe2 607 }
Pawel Zarembski 0:01f31e923fe2 608
Pawel Zarembski 0:01f31e923fe2 609 mask <<= 1;
Pawel Zarembski 0:01f31e923fe2 610 }
Pawel Zarembski 0:01f31e923fe2 611 }
Pawel Zarembski 0:01f31e923fe2 612
Pawel Zarembski 0:01f31e923fe2 613 if (irq_flags & MXC_F_USB_DEV_INTFL_DMA_ERR) {
Pawel Zarembski 0:01f31e923fe2 614 // Read and clear endpoint interrupts
Pawel Zarembski 0:01f31e923fe2 615 ep_int = MXC_USB->dma_err_int;
Pawel Zarembski 0:01f31e923fe2 616 MXC_USB->dma_err_int = ep_int;
Pawel Zarembski 0:01f31e923fe2 617 while(1); // not recoverable
Pawel Zarembski 0:01f31e923fe2 618 }
Pawel Zarembski 0:01f31e923fe2 619
Pawel Zarembski 0:01f31e923fe2 620 NVIC_EnableIRQ(USB_IRQn);
Pawel Zarembski 0:01f31e923fe2 621
Pawel Zarembski 0:01f31e923fe2 622 }