USBDevice for STM support

Dependents:   Nucleo_Usb_JoyMouse Nucleo_usbmouse ELEC350_1-referral-2018-usb-hid USBJoystick_HelloWorld2_wip ... more

This library contains all mbed usb device library (mbed-os\features\unsupported\USBDevice).

Committer:
frq08711@LMECWL0871.LME.ST.COM
Date:
Tue Mar 28 11:00:57 2017 +0200
Branch:
master
Revision:
4:50ec00aa4515
Parent:
1:2a3ae13b45ef
update for 5.4.2

Who changed what in which revision?

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