USBDevice with support for STM32F3
Fork of F042K6_USBDevice by
USBDevice/USBHAL_STM32L1.cpp@67:6099ce7e71c9, 2016-10-24 (annotated)
- Committer:
- Bradley Scott
- Date:
- Mon Oct 24 17:40:10 2016 +0100
- Revision:
- 67:6099ce7e71c9
- Parent:
- 66:b129e98ab7a0
- Child:
- 69:f8305faf7917
Add critical sections to keep endpoint accesses atomic.
Also reordered IRQ enabling/disabling to avoid enabling the IRQ
before the device has been fully initialized.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
58:68fad4f36f1c | 1 | /* Copyright (c) 2010-2015 mbed.org, MIT License |
va009039 |
58:68fad4f36f1c | 2 | * |
va009039 |
58:68fad4f36f1c | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
va009039 |
58:68fad4f36f1c | 4 | * and associated documentation files (the "Software"), to deal in the Software without |
va009039 |
58:68fad4f36f1c | 5 | * restriction, including without limitation the rights to use, copy, modify, merge, publish, |
va009039 |
58:68fad4f36f1c | 6 | * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the |
va009039 |
58:68fad4f36f1c | 7 | * Software is furnished to do so, subject to the following conditions: |
va009039 |
58:68fad4f36f1c | 8 | * |
va009039 |
58:68fad4f36f1c | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
va009039 |
58:68fad4f36f1c | 10 | * substantial portions of the Software. |
va009039 |
58:68fad4f36f1c | 11 | * |
va009039 |
58:68fad4f36f1c | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
va009039 |
58:68fad4f36f1c | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
va009039 |
58:68fad4f36f1c | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
va009039 |
58:68fad4f36f1c | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
va009039 |
58:68fad4f36f1c | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
va009039 |
58:68fad4f36f1c | 17 | */ |
va009039 |
58:68fad4f36f1c | 18 | |
Bradley Scott |
66:b129e98ab7a0 | 19 | #if defined(TARGET_STM32L1)||defined(TARGET_STM32F3)||defined(TARGET_STM32F1)||defined(TARGET_STM32F0) |
Bradley Scott |
66:b129e98ab7a0 | 20 | #include "pinmap.h" |
va009039 |
58:68fad4f36f1c | 21 | #include "USBDevice.h" |
va009039 |
58:68fad4f36f1c | 22 | |
va009039 |
62:23cb405e1ee5 | 23 | #if defined(TARGET_STM32F1) |
va009039 |
62:23cb405e1ee5 | 24 | #define USB_LP_IRQn USB_LP_CAN1_RX0_IRQn |
va009039 |
62:23cb405e1ee5 | 25 | const uint8_t PCD_EP_TYPE_CTRL = EP_TYPE_CTRL; |
va009039 |
62:23cb405e1ee5 | 26 | const uint8_t PCD_EP_TYPE_INTR = EP_TYPE_INTR; |
va009039 |
62:23cb405e1ee5 | 27 | const uint8_t PCD_EP_TYPE_BULK = EP_TYPE_BULK; |
va009039 |
62:23cb405e1ee5 | 28 | const uint8_t PCD_EP_TYPE_ISOC = EP_TYPE_ISOC; |
va009039 |
62:23cb405e1ee5 | 29 | |
va009039 |
62:23cb405e1ee5 | 30 | #elif defined(TARGET_STM32L1) |
va009039 |
62:23cb405e1ee5 | 31 | void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { |
va009039 |
62:23cb405e1ee5 | 32 | __SYSCFG_CLK_ENABLE(); // for SYSCFG_PMC_USB_PU |
va009039 |
62:23cb405e1ee5 | 33 | if (state == 1) { |
va009039 |
62:23cb405e1ee5 | 34 | __HAL_SYSCFG_USBPULLUP_ENABLE(); |
va009039 |
62:23cb405e1ee5 | 35 | } else { |
va009039 |
62:23cb405e1ee5 | 36 | __HAL_SYSCFG_USBPULLUP_DISABLE(); |
va009039 |
62:23cb405e1ee5 | 37 | } |
va009039 |
62:23cb405e1ee5 | 38 | } |
va009039 |
63:05e2f2e4dc3e | 39 | |
va009039 |
63:05e2f2e4dc3e | 40 | #elif defined(TARGET_STM32L0)||defined(TARGET_STM32F0) |
va009039 |
63:05e2f2e4dc3e | 41 | #define USB_LP_IRQn USB_IRQn |
va009039 |
63:05e2f2e4dc3e | 42 | void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { |
va009039 |
63:05e2f2e4dc3e | 43 | if (state == 1) { |
va009039 |
63:05e2f2e4dc3e | 44 | SET_BIT(USB->BCDR, USB_BCDR_DPPU); // DP Pull-up |
va009039 |
63:05e2f2e4dc3e | 45 | } else { |
va009039 |
63:05e2f2e4dc3e | 46 | CLEAR_BIT(USB->BCDR, USB_BCDR_DPPU); |
va009039 |
63:05e2f2e4dc3e | 47 | } |
va009039 |
63:05e2f2e4dc3e | 48 | } |
va009039 |
63:05e2f2e4dc3e | 49 | |
va009039 |
63:05e2f2e4dc3e | 50 | #elif defined(TARGET_STM32F3) |
Bradley Scott |
66:b129e98ab7a0 | 51 | #define USB_LP_IRQn USB_LP_CAN_RX0_IRQn |
va009039 |
62:23cb405e1ee5 | 52 | #endif |
va009039 |
62:23cb405e1ee5 | 53 | |
va009039 |
58:68fad4f36f1c | 54 | static PCD_HandleTypeDef hpcd_USB_FS; |
va009039 |
58:68fad4f36f1c | 55 | static volatile int epComplete = 0; |
va009039 |
58:68fad4f36f1c | 56 | |
va009039 |
58:68fad4f36f1c | 57 | USBHAL * USBHAL::instance; |
va009039 |
58:68fad4f36f1c | 58 | uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {return 0;} |
va009039 |
58:68fad4f36f1c | 59 | |
va009039 |
58:68fad4f36f1c | 60 | USBHAL::USBHAL(void) { |
Bradley Scott |
66:b129e98ab7a0 | 61 | #if defined(TARGET_STM32F3) |
Bradley Scott |
66:b129e98ab7a0 | 62 | // Configure USB pins |
Bradley Scott |
66:b129e98ab7a0 | 63 | pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB)); |
Bradley Scott |
66:b129e98ab7a0 | 64 | pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB)); |
Bradley Scott |
66:b129e98ab7a0 | 65 | #endif |
va009039 |
58:68fad4f36f1c | 66 | hpcd_USB_FS.pData = this; |
va009039 |
58:68fad4f36f1c | 67 | hpcd_USB_FS.Instance = USB; |
va009039 |
58:68fad4f36f1c | 68 | hpcd_USB_FS.Init.dev_endpoints = 8; |
va009039 |
58:68fad4f36f1c | 69 | hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; |
va009039 |
58:68fad4f36f1c | 70 | hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8; |
va009039 |
58:68fad4f36f1c | 71 | hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; |
va009039 |
58:68fad4f36f1c | 72 | hpcd_USB_FS.Init.Sof_enable = DISABLE; |
va009039 |
58:68fad4f36f1c | 73 | hpcd_USB_FS.Init.low_power_enable = DISABLE; |
va009039 |
58:68fad4f36f1c | 74 | hpcd_USB_FS.Init.battery_charging_enable = DISABLE; |
va009039 |
62:23cb405e1ee5 | 75 | NVIC_SetVector(USB_LP_IRQn, (uint32_t)&_usbisr); |
va009039 |
58:68fad4f36f1c | 76 | HAL_PCD_Init(&hpcd_USB_FS); |
va009039 |
62:23cb405e1ee5 | 77 | HAL_PCD_Start(&hpcd_USB_FS); |
va009039 |
58:68fad4f36f1c | 78 | } |
va009039 |
58:68fad4f36f1c | 79 | |
va009039 |
58:68fad4f36f1c | 80 | void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) { |
va009039 |
58:68fad4f36f1c | 81 | __USB_CLK_ENABLE(); |
va009039 |
58:68fad4f36f1c | 82 | HAL_NVIC_SetPriority(USB_LP_IRQn, 0, 0); |
va009039 |
58:68fad4f36f1c | 83 | } |
va009039 |
58:68fad4f36f1c | 84 | |
va009039 |
58:68fad4f36f1c | 85 | void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) { |
Bradley Scott |
67:6099ce7e71c9 | 86 | HAL_NVIC_DisableIRQ(USB_LP_IRQn); // Peripheral interrupt Deinit |
va009039 |
58:68fad4f36f1c | 87 | __USB_CLK_DISABLE(); // Peripheral clock disable |
va009039 |
58:68fad4f36f1c | 88 | } |
va009039 |
58:68fad4f36f1c | 89 | |
va009039 |
58:68fad4f36f1c | 90 | USBHAL::~USBHAL(void) { |
va009039 |
58:68fad4f36f1c | 91 | HAL_PCD_DeInit(&hpcd_USB_FS); |
va009039 |
58:68fad4f36f1c | 92 | } |
va009039 |
58:68fad4f36f1c | 93 | |
va009039 |
58:68fad4f36f1c | 94 | void USBHAL::connect(void) { |
Bradley Scott |
67:6099ce7e71c9 | 95 | HAL_NVIC_EnableIRQ(USB_LP_IRQn); |
va009039 |
58:68fad4f36f1c | 96 | HAL_PCD_DevConnect(&hpcd_USB_FS); |
va009039 |
58:68fad4f36f1c | 97 | } |
va009039 |
58:68fad4f36f1c | 98 | |
va009039 |
58:68fad4f36f1c | 99 | void USBHAL::disconnect(void) { |
va009039 |
58:68fad4f36f1c | 100 | HAL_PCD_DevDisconnect(&hpcd_USB_FS); |
Bradley Scott |
67:6099ce7e71c9 | 101 | HAL_NVIC_DisableIRQ(USB_LP_IRQn); |
va009039 |
58:68fad4f36f1c | 102 | } |
va009039 |
58:68fad4f36f1c | 103 | |
va009039 |
58:68fad4f36f1c | 104 | void USBHAL::configureDevice(void) { |
va009039 |
58:68fad4f36f1c | 105 | // Not needed |
va009039 |
58:68fad4f36f1c | 106 | } |
va009039 |
58:68fad4f36f1c | 107 | void USBHAL::unconfigureDevice(void) { |
va009039 |
58:68fad4f36f1c | 108 | // Not needed |
va009039 |
58:68fad4f36f1c | 109 | } |
va009039 |
58:68fad4f36f1c | 110 | |
va009039 |
58:68fad4f36f1c | 111 | void USBHAL::setAddress(uint8_t address) { |
va009039 |
58:68fad4f36f1c | 112 | HAL_PCD_SetAddress(&hpcd_USB_FS, address); |
va009039 |
58:68fad4f36f1c | 113 | } |
va009039 |
58:68fad4f36f1c | 114 | |
va009039 |
58:68fad4f36f1c | 115 | class PacketBufferAreaManager { |
va009039 |
58:68fad4f36f1c | 116 | public: |
va009039 |
59:5d5e3685bd60 | 117 | PacketBufferAreaManager(int bufsize_):bufsize(bufsize_) { |
va009039 |
58:68fad4f36f1c | 118 | reset(); |
va009039 |
58:68fad4f36f1c | 119 | } |
va009039 |
58:68fad4f36f1c | 120 | void reset() { |
va009039 |
58:68fad4f36f1c | 121 | head = 0; |
va009039 |
59:5d5e3685bd60 | 122 | tail = bufsize; |
va009039 |
58:68fad4f36f1c | 123 | } |
va009039 |
58:68fad4f36f1c | 124 | int allocBuf(int maxPacketSize) { |
va009039 |
58:68fad4f36f1c | 125 | head += 4; |
va009039 |
58:68fad4f36f1c | 126 | tail -= maxPacketSize; |
va009039 |
58:68fad4f36f1c | 127 | if (tail < head) { |
va009039 |
58:68fad4f36f1c | 128 | return 0; |
va009039 |
58:68fad4f36f1c | 129 | } |
va009039 |
58:68fad4f36f1c | 130 | return tail; |
va009039 |
58:68fad4f36f1c | 131 | } |
va009039 |
58:68fad4f36f1c | 132 | private: |
va009039 |
58:68fad4f36f1c | 133 | int head,tail; |
va009039 |
59:5d5e3685bd60 | 134 | int bufsize; |
va009039 |
59:5d5e3685bd60 | 135 | } PktBufArea(512); |
va009039 |
58:68fad4f36f1c | 136 | |
va009039 |
58:68fad4f36f1c | 137 | bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { |
va009039 |
58:68fad4f36f1c | 138 | int pmaadress = PktBufArea.allocBuf(maxPacket); |
va009039 |
58:68fad4f36f1c | 139 | MBED_ASSERT(pmaadress != 0); |
va009039 |
58:68fad4f36f1c | 140 | if (pmaadress == 0) { |
va009039 |
58:68fad4f36f1c | 141 | return false; |
va009039 |
58:68fad4f36f1c | 142 | } |
va009039 |
58:68fad4f36f1c | 143 | PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; |
va009039 |
58:68fad4f36f1c | 144 | uint8_t ep_type; |
va009039 |
58:68fad4f36f1c | 145 | switch(endpoint) { |
va009039 |
58:68fad4f36f1c | 146 | case EP0OUT: |
va009039 |
58:68fad4f36f1c | 147 | HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 148 | HAL_PCD_EP_Open(hpcd, 0x00, maxPacket, PCD_EP_TYPE_CTRL); |
va009039 |
58:68fad4f36f1c | 149 | break; |
va009039 |
58:68fad4f36f1c | 150 | case EP0IN: |
va009039 |
58:68fad4f36f1c | 151 | HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 152 | HAL_PCD_EP_Open(hpcd, 0x80, maxPacket, PCD_EP_TYPE_CTRL); |
va009039 |
58:68fad4f36f1c | 153 | break; |
va009039 |
58:68fad4f36f1c | 154 | case EPINT_OUT: |
va009039 |
58:68fad4f36f1c | 155 | HAL_PCDEx_PMAConfig(hpcd, 0x01, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 156 | HAL_PCD_EP_Open(hpcd, 0x01, maxPacket, PCD_EP_TYPE_INTR); |
va009039 |
58:68fad4f36f1c | 157 | break; |
va009039 |
58:68fad4f36f1c | 158 | case EPINT_IN: |
va009039 |
58:68fad4f36f1c | 159 | HAL_PCDEx_PMAConfig(hpcd, 0x81, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 160 | HAL_PCD_EP_Open(hpcd, 0x81, maxPacket, PCD_EP_TYPE_INTR); |
va009039 |
58:68fad4f36f1c | 161 | break; |
va009039 |
58:68fad4f36f1c | 162 | case EPBULK_OUT: |
va009039 |
58:68fad4f36f1c | 163 | HAL_PCDEx_PMAConfig(hpcd, 0x02, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 164 | HAL_PCD_EP_Open(hpcd, 0x02, maxPacket, PCD_EP_TYPE_BULK); |
va009039 |
58:68fad4f36f1c | 165 | break; |
va009039 |
58:68fad4f36f1c | 166 | case EPBULK_IN: |
va009039 |
58:68fad4f36f1c | 167 | HAL_PCDEx_PMAConfig(hpcd, 0x82, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 168 | HAL_PCD_EP_Open(hpcd, 0x82, maxPacket, PCD_EP_TYPE_BULK); |
va009039 |
58:68fad4f36f1c | 169 | break; |
va009039 |
58:68fad4f36f1c | 170 | case EP3OUT: |
va009039 |
58:68fad4f36f1c | 171 | HAL_PCDEx_PMAConfig(hpcd, 0x03, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 172 | ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; |
va009039 |
58:68fad4f36f1c | 173 | HAL_PCD_EP_Open(hpcd, 0x03, maxPacket, ep_type); |
va009039 |
58:68fad4f36f1c | 174 | break; |
va009039 |
58:68fad4f36f1c | 175 | case EP3IN: |
va009039 |
58:68fad4f36f1c | 176 | HAL_PCDEx_PMAConfig(hpcd, 0x83, PCD_SNG_BUF, pmaadress); |
va009039 |
58:68fad4f36f1c | 177 | ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; |
va009039 |
58:68fad4f36f1c | 178 | HAL_PCD_EP_Open(hpcd, 0x83, maxPacket, ep_type); |
va009039 |
58:68fad4f36f1c | 179 | break; |
va009039 |
58:68fad4f36f1c | 180 | default: |
va009039 |
58:68fad4f36f1c | 181 | MBED_ASSERT(0); |
va009039 |
58:68fad4f36f1c | 182 | return false; |
va009039 |
58:68fad4f36f1c | 183 | } |
va009039 |
58:68fad4f36f1c | 184 | return true; |
va009039 |
58:68fad4f36f1c | 185 | } |
va009039 |
58:68fad4f36f1c | 186 | |
va009039 |
58:68fad4f36f1c | 187 | // read setup packet |
va009039 |
58:68fad4f36f1c | 188 | void USBHAL::EP0setup(uint8_t *buffer) { |
va009039 |
58:68fad4f36f1c | 189 | memcpy(buffer, hpcd_USB_FS.Setup, 8); |
va009039 |
58:68fad4f36f1c | 190 | } |
va009039 |
58:68fad4f36f1c | 191 | |
va009039 |
58:68fad4f36f1c | 192 | void USBHAL::EP0readStage(void) { |
va009039 |
58:68fad4f36f1c | 193 | } |
va009039 |
58:68fad4f36f1c | 194 | |
va009039 |
58:68fad4f36f1c | 195 | void USBHAL::EP0read(void) { |
va009039 |
58:68fad4f36f1c | 196 | endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); |
va009039 |
58:68fad4f36f1c | 197 | } |
va009039 |
58:68fad4f36f1c | 198 | |
va009039 |
59:5d5e3685bd60 | 199 | class rxTempBufferManager { |
va009039 |
59:5d5e3685bd60 | 200 | uint8_t buf0[MAX_PACKET_SIZE_EP0]; |
va009039 |
59:5d5e3685bd60 | 201 | uint8_t buf1[MAX_PACKET_SIZE_EP1]; |
va009039 |
59:5d5e3685bd60 | 202 | uint8_t buf2[MAX_PACKET_SIZE_EP2]; |
va009039 |
59:5d5e3685bd60 | 203 | uint8_t buf3[MAX_PACKET_SIZE_EP3_ISO]; |
va009039 |
59:5d5e3685bd60 | 204 | public: |
va009039 |
59:5d5e3685bd60 | 205 | uint8_t* ptr(uint8_t endpoint, int maxPacketSize) { |
va009039 |
59:5d5e3685bd60 | 206 | switch(endpoint) { |
va009039 |
59:5d5e3685bd60 | 207 | case EP0OUT: |
va009039 |
59:5d5e3685bd60 | 208 | MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP0); |
va009039 |
59:5d5e3685bd60 | 209 | break; |
va009039 |
59:5d5e3685bd60 | 210 | case EP1OUT: |
va009039 |
59:5d5e3685bd60 | 211 | MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP1); |
va009039 |
59:5d5e3685bd60 | 212 | break; |
va009039 |
59:5d5e3685bd60 | 213 | case EP2OUT: |
va009039 |
59:5d5e3685bd60 | 214 | MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP2); |
va009039 |
59:5d5e3685bd60 | 215 | break; |
va009039 |
59:5d5e3685bd60 | 216 | case EP3OUT: |
va009039 |
59:5d5e3685bd60 | 217 | MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP3_ISO); |
va009039 |
59:5d5e3685bd60 | 218 | break; |
va009039 |
59:5d5e3685bd60 | 219 | } |
va009039 |
59:5d5e3685bd60 | 220 | return ptr(endpoint); |
va009039 |
58:68fad4f36f1c | 221 | } |
va009039 |
59:5d5e3685bd60 | 222 | uint8_t* ptr(uint8_t endpoint) { |
va009039 |
59:5d5e3685bd60 | 223 | switch(endpoint) { |
va009039 |
59:5d5e3685bd60 | 224 | case EP0OUT: return buf0; |
va009039 |
59:5d5e3685bd60 | 225 | case EP1OUT: return buf1; |
va009039 |
59:5d5e3685bd60 | 226 | case EP2OUT: return buf2; |
va009039 |
59:5d5e3685bd60 | 227 | case EP3OUT: return buf3; |
va009039 |
59:5d5e3685bd60 | 228 | } |
va009039 |
59:5d5e3685bd60 | 229 | MBED_ASSERT(0); |
va009039 |
59:5d5e3685bd60 | 230 | return NULL; |
va009039 |
59:5d5e3685bd60 | 231 | } |
va009039 |
59:5d5e3685bd60 | 232 | } rxtmp; |
va009039 |
58:68fad4f36f1c | 233 | |
va009039 |
58:68fad4f36f1c | 234 | uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { |
va009039 |
58:68fad4f36f1c | 235 | const uint8_t endpoint = EP0OUT; |
va009039 |
58:68fad4f36f1c | 236 | uint32_t length = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); |
va009039 |
59:5d5e3685bd60 | 237 | memcpy(buffer, rxtmp.ptr(endpoint), length); |
va009039 |
58:68fad4f36f1c | 238 | return length; |
va009039 |
58:68fad4f36f1c | 239 | } |
va009039 |
58:68fad4f36f1c | 240 | |
va009039 |
58:68fad4f36f1c | 241 | void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { |
va009039 |
58:68fad4f36f1c | 242 | endpointWrite(EP0IN, buffer, size); |
va009039 |
58:68fad4f36f1c | 243 | } |
va009039 |
58:68fad4f36f1c | 244 | |
va009039 |
58:68fad4f36f1c | 245 | void USBHAL::EP0getWriteResult(void) { |
va009039 |
58:68fad4f36f1c | 246 | } |
va009039 |
58:68fad4f36f1c | 247 | |
va009039 |
58:68fad4f36f1c | 248 | void USBHAL::EP0stall(void) { |
va009039 |
58:68fad4f36f1c | 249 | // If we stall the out endpoint here then we have problems transferring |
va009039 |
58:68fad4f36f1c | 250 | // and setup requests after the (stalled) get device qualifier requests. |
va009039 |
58:68fad4f36f1c | 251 | // TODO: Find out if this is correct behavior, or whether we are doing |
va009039 |
58:68fad4f36f1c | 252 | // something else wrong |
va009039 |
58:68fad4f36f1c | 253 | stallEndpoint(EP0IN); |
va009039 |
58:68fad4f36f1c | 254 | // stallEndpoint(EP0OUT); |
va009039 |
58:68fad4f36f1c | 255 | } |
va009039 |
58:68fad4f36f1c | 256 | |
va009039 |
58:68fad4f36f1c | 257 | EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { |
Bradley Scott |
67:6099ce7e71c9 | 258 | core_util_critical_section_enter(); |
va009039 |
59:5d5e3685bd60 | 259 | HAL_PCD_EP_Receive(&hpcd_USB_FS, endpoint>>1, rxtmp.ptr(endpoint, maximumSize), maximumSize); |
va009039 |
58:68fad4f36f1c | 260 | epComplete &= ~(1 << endpoint); |
Bradley Scott |
67:6099ce7e71c9 | 261 | core_util_critical_section_exit(); |
va009039 |
58:68fad4f36f1c | 262 | return EP_PENDING; |
va009039 |
58:68fad4f36f1c | 263 | } |
va009039 |
58:68fad4f36f1c | 264 | |
va009039 |
58:68fad4f36f1c | 265 | EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { |
va009039 |
58:68fad4f36f1c | 266 | if (!(epComplete & (1 << endpoint))) { |
va009039 |
58:68fad4f36f1c | 267 | return EP_PENDING; |
va009039 |
58:68fad4f36f1c | 268 | } |
va009039 |
58:68fad4f36f1c | 269 | int len = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); |
va009039 |
59:5d5e3685bd60 | 270 | memcpy(buffer, rxtmp.ptr(endpoint), len); |
va009039 |
58:68fad4f36f1c | 271 | *bytesRead = len; |
va009039 |
58:68fad4f36f1c | 272 | return EP_COMPLETED; |
va009039 |
58:68fad4f36f1c | 273 | } |
va009039 |
58:68fad4f36f1c | 274 | |
va009039 |
58:68fad4f36f1c | 275 | EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { |
Bradley Scott |
67:6099ce7e71c9 | 276 | core_util_critical_section_enter(); |
va009039 |
58:68fad4f36f1c | 277 | HAL_PCD_EP_Transmit(&hpcd_USB_FS, endpoint>>1, data, size); |
va009039 |
58:68fad4f36f1c | 278 | epComplete &= ~(1 << endpoint); |
Bradley Scott |
67:6099ce7e71c9 | 279 | core_util_critical_section_exit(); |
va009039 |
58:68fad4f36f1c | 280 | return EP_PENDING; |
va009039 |
58:68fad4f36f1c | 281 | } |
va009039 |
58:68fad4f36f1c | 282 | |
va009039 |
58:68fad4f36f1c | 283 | EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { |
va009039 |
58:68fad4f36f1c | 284 | if (epComplete & (1 << endpoint)) { |
Bradley Scott |
67:6099ce7e71c9 | 285 | core_util_critical_section_enter(); |
va009039 |
58:68fad4f36f1c | 286 | epComplete &= ~(1 << endpoint); |
Bradley Scott |
67:6099ce7e71c9 | 287 | core_util_critical_section_exit(); |
va009039 |
58:68fad4f36f1c | 288 | return EP_COMPLETED; |
va009039 |
58:68fad4f36f1c | 289 | } |
va009039 |
58:68fad4f36f1c | 290 | return EP_PENDING; |
va009039 |
58:68fad4f36f1c | 291 | } |
va009039 |
58:68fad4f36f1c | 292 | |
va009039 |
58:68fad4f36f1c | 293 | void USBHAL::stallEndpoint(uint8_t endpoint) { |
va009039 |
58:68fad4f36f1c | 294 | PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; |
va009039 |
58:68fad4f36f1c | 295 | switch(endpoint) { |
va009039 |
58:68fad4f36f1c | 296 | case EP0IN: |
va009039 |
58:68fad4f36f1c | 297 | HAL_PCD_EP_SetStall(hpcd, 0x80); |
va009039 |
58:68fad4f36f1c | 298 | break; |
va009039 |
58:68fad4f36f1c | 299 | case EP0OUT: |
va009039 |
58:68fad4f36f1c | 300 | HAL_PCD_EP_SetStall(hpcd, 0x00); |
va009039 |
58:68fad4f36f1c | 301 | break; |
va009039 |
58:68fad4f36f1c | 302 | default: |
va009039 |
58:68fad4f36f1c | 303 | break; |
va009039 |
58:68fad4f36f1c | 304 | } |
va009039 |
58:68fad4f36f1c | 305 | } |
va009039 |
58:68fad4f36f1c | 306 | |
va009039 |
58:68fad4f36f1c | 307 | void USBHAL::unstallEndpoint(uint8_t endpoint) { |
va009039 |
58:68fad4f36f1c | 308 | } |
va009039 |
58:68fad4f36f1c | 309 | |
va009039 |
58:68fad4f36f1c | 310 | bool USBHAL::getEndpointStallState(uint8_t endpoint) { |
va009039 |
58:68fad4f36f1c | 311 | return false; |
va009039 |
58:68fad4f36f1c | 312 | } |
va009039 |
58:68fad4f36f1c | 313 | |
va009039 |
58:68fad4f36f1c | 314 | void USBHAL::remoteWakeup(void) {} |
va009039 |
62:23cb405e1ee5 | 315 | |
va009039 |
62:23cb405e1ee5 | 316 | void USBHAL::_usbisr(void) { |
va009039 |
62:23cb405e1ee5 | 317 | HAL_PCD_IRQHandler(&hpcd_USB_FS); |
va009039 |
62:23cb405e1ee5 | 318 | } |
va009039 |
62:23cb405e1ee5 | 319 | |
va009039 |
58:68fad4f36f1c | 320 | void USBHAL::usbisr(void) {} |
va009039 |
58:68fad4f36f1c | 321 | |
va009039 |
58:68fad4f36f1c | 322 | void USBHAL::SetupStageCallback() { |
va009039 |
58:68fad4f36f1c | 323 | EP0setupCallback(); |
va009039 |
58:68fad4f36f1c | 324 | } |
va009039 |
58:68fad4f36f1c | 325 | |
va009039 |
58:68fad4f36f1c | 326 | void USBHAL::DataInStageCallback(uint8_t epnum) { |
va009039 |
58:68fad4f36f1c | 327 | switch(epnum) { |
va009039 |
58:68fad4f36f1c | 328 | case 0: // EP0IN |
va009039 |
58:68fad4f36f1c | 329 | EP0in(); |
va009039 |
58:68fad4f36f1c | 330 | break; |
va009039 |
58:68fad4f36f1c | 331 | case 1: |
va009039 |
58:68fad4f36f1c | 332 | epComplete |= (1<<EP1IN); |
va009039 |
58:68fad4f36f1c | 333 | if (EP1_IN_callback()) { |
va009039 |
58:68fad4f36f1c | 334 | epComplete &= ~(1<<EP1IN); |
va009039 |
58:68fad4f36f1c | 335 | } |
va009039 |
58:68fad4f36f1c | 336 | break; |
va009039 |
58:68fad4f36f1c | 337 | case 2: |
va009039 |
58:68fad4f36f1c | 338 | epComplete |= (1<<EP2IN); |
va009039 |
58:68fad4f36f1c | 339 | if (EP2_IN_callback()) { |
va009039 |
58:68fad4f36f1c | 340 | epComplete &= ~(1<<EP2IN); |
va009039 |
58:68fad4f36f1c | 341 | } |
va009039 |
58:68fad4f36f1c | 342 | break; |
va009039 |
58:68fad4f36f1c | 343 | case 3: |
va009039 |
58:68fad4f36f1c | 344 | epComplete |= (1<<EP3IN); |
va009039 |
58:68fad4f36f1c | 345 | if (EP3_IN_callback()) { |
va009039 |
58:68fad4f36f1c | 346 | epComplete &= ~(1<<EP3IN); |
va009039 |
58:68fad4f36f1c | 347 | } |
va009039 |
58:68fad4f36f1c | 348 | break; |
va009039 |
58:68fad4f36f1c | 349 | default: |
va009039 |
58:68fad4f36f1c | 350 | MBED_ASSERT(0); |
va009039 |
58:68fad4f36f1c | 351 | break; |
va009039 |
58:68fad4f36f1c | 352 | } |
va009039 |
58:68fad4f36f1c | 353 | } |
va009039 |
58:68fad4f36f1c | 354 | |
va009039 |
58:68fad4f36f1c | 355 | void USBHAL::DataOutStageCallback(uint8_t epnum) { |
va009039 |
58:68fad4f36f1c | 356 | switch(epnum) { |
va009039 |
58:68fad4f36f1c | 357 | case 0: // EP0OUT |
va009039 |
59:5d5e3685bd60 | 358 | if ((hpcd_USB_FS.Setup[0]&0x80) == 0x00) { // host to device ? |
va009039 |
59:5d5e3685bd60 | 359 | EP0out(); |
va009039 |
59:5d5e3685bd60 | 360 | } |
va009039 |
58:68fad4f36f1c | 361 | break; |
va009039 |
58:68fad4f36f1c | 362 | case 1: |
va009039 |
58:68fad4f36f1c | 363 | epComplete |= (1<<EP1OUT); |
va009039 |
58:68fad4f36f1c | 364 | if (EP1_OUT_callback()) { |
va009039 |
58:68fad4f36f1c | 365 | epComplete &= ~(1<<EP1OUT); |
va009039 |
58:68fad4f36f1c | 366 | } |
va009039 |
58:68fad4f36f1c | 367 | break; |
va009039 |
58:68fad4f36f1c | 368 | case 2: |
va009039 |
58:68fad4f36f1c | 369 | epComplete |= (1<<EP2OUT); |
va009039 |
58:68fad4f36f1c | 370 | if (EP2_OUT_callback()) { |
va009039 |
58:68fad4f36f1c | 371 | epComplete &= ~(1<<EP2OUT); |
va009039 |
58:68fad4f36f1c | 372 | } |
va009039 |
58:68fad4f36f1c | 373 | break; |
va009039 |
58:68fad4f36f1c | 374 | case 3: |
va009039 |
58:68fad4f36f1c | 375 | epComplete |= (1<<EP3OUT); |
va009039 |
58:68fad4f36f1c | 376 | if (EP3_OUT_callback()) { |
va009039 |
58:68fad4f36f1c | 377 | epComplete &= ~(1<<EP3OUT); |
va009039 |
58:68fad4f36f1c | 378 | } |
va009039 |
58:68fad4f36f1c | 379 | break; |
va009039 |
58:68fad4f36f1c | 380 | default: |
va009039 |
58:68fad4f36f1c | 381 | MBED_ASSERT(0); |
va009039 |
58:68fad4f36f1c | 382 | break; |
va009039 |
58:68fad4f36f1c | 383 | } |
va009039 |
58:68fad4f36f1c | 384 | } |
va009039 |
58:68fad4f36f1c | 385 | |
va009039 |
58:68fad4f36f1c | 386 | void USBHAL::ResetCallback() { |
va009039 |
58:68fad4f36f1c | 387 | PktBufArea.reset(); |
va009039 |
58:68fad4f36f1c | 388 | realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); |
va009039 |
58:68fad4f36f1c | 389 | realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); |
va009039 |
58:68fad4f36f1c | 390 | } |
va009039 |
58:68fad4f36f1c | 391 | |
va009039 |
58:68fad4f36f1c | 392 | void USBHAL::SOFCallback() { |
va009039 |
63:05e2f2e4dc3e | 393 | SOF(hpcd_USB_FS.Instance->FNR & USB_FNR_FN); |
va009039 |
58:68fad4f36f1c | 394 | } |
va009039 |
58:68fad4f36f1c | 395 | |
va009039 |
58:68fad4f36f1c | 396 | void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { |
va009039 |
58:68fad4f36f1c | 397 | reinterpret_cast<USBHAL*>(hpcd->pData)->SetupStageCallback(); |
va009039 |
58:68fad4f36f1c | 398 | } |
va009039 |
58:68fad4f36f1c | 399 | |
va009039 |
58:68fad4f36f1c | 400 | void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { |
va009039 |
58:68fad4f36f1c | 401 | reinterpret_cast<USBHAL*>(hpcd->pData)->DataInStageCallback(epnum); |
va009039 |
58:68fad4f36f1c | 402 | } |
va009039 |
58:68fad4f36f1c | 403 | |
va009039 |
58:68fad4f36f1c | 404 | void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { |
va009039 |
58:68fad4f36f1c | 405 | reinterpret_cast<USBHAL*>(hpcd->pData)->DataOutStageCallback(epnum); |
va009039 |
58:68fad4f36f1c | 406 | } |
va009039 |
58:68fad4f36f1c | 407 | |
va009039 |
58:68fad4f36f1c | 408 | void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) { |
va009039 |
58:68fad4f36f1c | 409 | reinterpret_cast<USBHAL*>(hpcd->pData)->ResetCallback(); |
va009039 |
58:68fad4f36f1c | 410 | } |
va009039 |
58:68fad4f36f1c | 411 | |
va009039 |
58:68fad4f36f1c | 412 | void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { |
va009039 |
58:68fad4f36f1c | 413 | reinterpret_cast<USBHAL*>(hpcd->pData)->SOFCallback(); |
va009039 |
58:68fad4f36f1c | 414 | } |
va009039 |
58:68fad4f36f1c | 415 | |
va009039 |
58:68fad4f36f1c | 416 | void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) { |
va009039 |
58:68fad4f36f1c | 417 | if (hpcd->Init.low_power_enable) { |
va009039 |
58:68fad4f36f1c | 418 | SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); |
va009039 |
58:68fad4f36f1c | 419 | } |
va009039 |
58:68fad4f36f1c | 420 | } |
va009039 |
58:68fad4f36f1c | 421 | |
va009039 |
58:68fad4f36f1c | 422 | #endif |