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 /*
Pawel Zarembski 0:01f31e923fe2 2 * Copyright (c) 2004-2016 ARM Limited. All rights reserved.
Pawel Zarembski 0:01f31e923fe2 3 *
Pawel Zarembski 0:01f31e923fe2 4 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 5 *
Pawel Zarembski 0:01f31e923fe2 6 * Licensed under the Apache License, Version 2.0 (the License); you may
Pawel Zarembski 0:01f31e923fe2 7 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 8 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 9 *
Pawel Zarembski 0:01f31e923fe2 10 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 11 *
Pawel Zarembski 0:01f31e923fe2 12 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 15 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 16 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 17 */
Pawel Zarembski 0:01f31e923fe2 18
Pawel Zarembski 0:01f31e923fe2 19 /*----------------------------------------------------------------------------
Pawel Zarembski 0:01f31e923fe2 20 * RL-ARM - USB
Pawel Zarembski 0:01f31e923fe2 21 *----------------------------------------------------------------------------
Pawel Zarembski 0:01f31e923fe2 22 * Name: usbd_STM32F103.c
Pawel Zarembski 0:01f31e923fe2 23 * Purpose: Hardware Layer module for ST STM32F103
Pawel Zarembski 0:01f31e923fe2 24 * Rev.: V4.70
Pawel Zarembski 0:01f31e923fe2 25 *---------------------------------------------------------------------------*/
Pawel Zarembski 0:01f31e923fe2 26
Pawel Zarembski 0:01f31e923fe2 27 /* Double Buffering is not supported */
Pawel Zarembski 0:01f31e923fe2 28
Pawel Zarembski 0:01f31e923fe2 29 #include <rl_usb.h>
Pawel Zarembski 0:01f31e923fe2 30 #include "stm32f1xx.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "usbreg.h"
Pawel Zarembski 0:01f31e923fe2 32 #include "IO_Config.h"
Pawel Zarembski 0:01f31e923fe2 33 #include "cortex_m.h"
Pawel Zarembski 0:01f31e923fe2 34 #include "string.h"
Pawel Zarembski 0:01f31e923fe2 35
Pawel Zarembski 0:01f31e923fe2 36 #define __NO_USB_LIB_C
Pawel Zarembski 0:01f31e923fe2 37 #include "usb_config.c"
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 #define USB_ISTR_W0C_MASK (ISTR_PMAOVR | ISTR_ERR | ISTR_WKUP | ISTR_SUSP | ISTR_RESET | ISTR_SOF | ISTR_ESOF)
Pawel Zarembski 0:01f31e923fe2 40 #define VAL_MASK 0xFFFF
Pawel Zarembski 0:01f31e923fe2 41 #define VAL_SHIFT 16
Pawel Zarembski 0:01f31e923fe2 42 #define EP_NUM_MASK 0xFFFF
Pawel Zarembski 0:01f31e923fe2 43 #define EP_NUM_SHIFT 0
Pawel Zarembski 0:01f31e923fe2 44
Pawel Zarembski 0:01f31e923fe2 45 #define USB_DBL_BUF_EP 0x0000
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 #define EP_BUF_ADDR (sizeof(EP_BUF_DSCR)*(USBD_EP_NUM+1)) /* Endpoint Buf Adr */
Pawel Zarembski 0:01f31e923fe2 48
Pawel Zarembski 0:01f31e923fe2 49 EP_BUF_DSCR *pBUF_DSCR = (EP_BUF_DSCR *)USB_PMA_ADDR; /* Ptr to EP Buf Desc */
Pawel Zarembski 0:01f31e923fe2 50
Pawel Zarembski 0:01f31e923fe2 51 U16 FreeBufAddr; /* Endpoint Free Buffer Address */
Pawel Zarembski 0:01f31e923fe2 52
Pawel Zarembski 0:01f31e923fe2 53 uint32_t StatQueue[(USBD_EP_NUM + 1) * 2 + 1];
Pawel Zarembski 0:01f31e923fe2 54 uint32_t StatQueueHead = 0;
Pawel Zarembski 0:01f31e923fe2 55 uint32_t StatQueueTail = 0;
Pawel Zarembski 0:01f31e923fe2 56 uint32_t LastIstr = 0;
Pawel Zarembski 0:01f31e923fe2 57
Pawel Zarembski 0:01f31e923fe2 58
Pawel Zarembski 0:01f31e923fe2 59 inline static void stat_enque(uint32_t stat)
Pawel Zarembski 0:01f31e923fe2 60 {
Pawel Zarembski 0:01f31e923fe2 61 cortex_int_state_t state;
Pawel Zarembski 0:01f31e923fe2 62 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 63 StatQueue[StatQueueTail] = stat;
Pawel Zarembski 0:01f31e923fe2 64 StatQueueTail = (StatQueueTail + 1) % (sizeof(StatQueue) / sizeof(StatQueue[0]));
Pawel Zarembski 0:01f31e923fe2 65 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 66 }
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 inline static uint32_t stat_deque()
Pawel Zarembski 0:01f31e923fe2 69 {
Pawel Zarembski 0:01f31e923fe2 70 cortex_int_state_t state;
Pawel Zarembski 0:01f31e923fe2 71 uint32_t stat;
Pawel Zarembski 0:01f31e923fe2 72 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 73 stat = StatQueue[StatQueueHead];
Pawel Zarembski 0:01f31e923fe2 74 StatQueueHead = (StatQueueHead + 1) % (sizeof(StatQueue) / sizeof(StatQueue[0]));
Pawel Zarembski 0:01f31e923fe2 75 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 76
Pawel Zarembski 0:01f31e923fe2 77 return stat;
Pawel Zarembski 0:01f31e923fe2 78 }
Pawel Zarembski 0:01f31e923fe2 79
Pawel Zarembski 0:01f31e923fe2 80 inline static uint32_t stat_is_empty()
Pawel Zarembski 0:01f31e923fe2 81 {
Pawel Zarembski 0:01f31e923fe2 82 cortex_int_state_t state;
Pawel Zarembski 0:01f31e923fe2 83 uint32_t empty;
Pawel Zarembski 0:01f31e923fe2 84 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 85 empty = StatQueueHead == StatQueueTail;
Pawel Zarembski 0:01f31e923fe2 86 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 87 return empty;
Pawel Zarembski 0:01f31e923fe2 88 }
Pawel Zarembski 0:01f31e923fe2 89
Pawel Zarembski 0:01f31e923fe2 90
Pawel Zarembski 0:01f31e923fe2 91 /*
Pawel Zarembski 0:01f31e923fe2 92 * Reset Endpoint
Pawel Zarembski 0:01f31e923fe2 93 * Parameters: EPNum: Endpoint Number
Pawel Zarembski 0:01f31e923fe2 94 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 95 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 96 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 97 */
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99 void EP_Reset(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 100 {
Pawel Zarembski 0:01f31e923fe2 101 U32 num, val;
Pawel Zarembski 0:01f31e923fe2 102 num = EPNum & 0x0F;
Pawel Zarembski 0:01f31e923fe2 103 val = EPxREG(num);
Pawel Zarembski 0:01f31e923fe2 104
Pawel Zarembski 0:01f31e923fe2 105 if (EPNum & 0x80) { /* IN Endpoint */
Pawel Zarembski 0:01f31e923fe2 106 EPxREG(num) = val & (EP_MASK | EP_DTOG_TX);
Pawel Zarembski 0:01f31e923fe2 107 } else { /* OUT Endpoint */
Pawel Zarembski 0:01f31e923fe2 108 EPxREG(num) = val & (EP_MASK | EP_DTOG_RX);
Pawel Zarembski 0:01f31e923fe2 109 }
Pawel Zarembski 0:01f31e923fe2 110 }
Pawel Zarembski 0:01f31e923fe2 111
Pawel Zarembski 0:01f31e923fe2 112
Pawel Zarembski 0:01f31e923fe2 113 /*
Pawel Zarembski 0:01f31e923fe2 114 * Set Endpoint Status
Pawel Zarembski 0:01f31e923fe2 115 * Parameters: EPNum: Endpoint Number
Pawel Zarembski 0:01f31e923fe2 116 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 117 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 118 * stat: New Status
Pawel Zarembski 0:01f31e923fe2 119 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 120 */
Pawel Zarembski 0:01f31e923fe2 121
Pawel Zarembski 0:01f31e923fe2 122 void EP_Status(U32 EPNum, U32 stat)
Pawel Zarembski 0:01f31e923fe2 123 {
Pawel Zarembski 0:01f31e923fe2 124 U32 num, val;
Pawel Zarembski 0:01f31e923fe2 125 num = EPNum & 0x0F;
Pawel Zarembski 0:01f31e923fe2 126 val = EPxREG(num);
Pawel Zarembski 0:01f31e923fe2 127
Pawel Zarembski 0:01f31e923fe2 128 if (EPNum & 0x80) { /* IN Endpoint */
Pawel Zarembski 0:01f31e923fe2 129 EPxREG(num) = EP_VAL_UNCHANGED(val) | ((val ^ stat) & EP_STAT_TX);
Pawel Zarembski 0:01f31e923fe2 130 } else { /* OUT Endpoint */
Pawel Zarembski 0:01f31e923fe2 131 EPxREG(num) = EP_VAL_UNCHANGED(val) | ((val ^ stat) & EP_STAT_RX);
Pawel Zarembski 0:01f31e923fe2 132 }
Pawel Zarembski 0:01f31e923fe2 133 }
Pawel Zarembski 0:01f31e923fe2 134
Pawel Zarembski 0:01f31e923fe2 135
Pawel Zarembski 0:01f31e923fe2 136 /*
Pawel Zarembski 0:01f31e923fe2 137 * USB Device Interrupt enable
Pawel Zarembski 0:01f31e923fe2 138 * Called by USBD_Init to enable the USB Interrupt
Pawel Zarembski 0:01f31e923fe2 139 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 140 */
Pawel Zarembski 0:01f31e923fe2 141
Pawel Zarembski 0:01f31e923fe2 142 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 143 void __svc(1) USBD_IntrEna(void);
Pawel Zarembski 0:01f31e923fe2 144 void __SVC_1(void)
Pawel Zarembski 0:01f31e923fe2 145 {
Pawel Zarembski 0:01f31e923fe2 146 #else
Pawel Zarembski 0:01f31e923fe2 147 void USBD_IntrEna(void)
Pawel Zarembski 0:01f31e923fe2 148 {
Pawel Zarembski 0:01f31e923fe2 149 #endif
Pawel Zarembski 0:01f31e923fe2 150 NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
Pawel Zarembski 0:01f31e923fe2 151 }
Pawel Zarembski 0:01f31e923fe2 152
Pawel Zarembski 0:01f31e923fe2 153
Pawel Zarembski 0:01f31e923fe2 154 /*
Pawel Zarembski 0:01f31e923fe2 155 * USB Device Initialize Function
Pawel Zarembski 0:01f31e923fe2 156 * Called by the User to initialize USB
Pawel Zarembski 0:01f31e923fe2 157 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 158 */
Pawel Zarembski 0:01f31e923fe2 159
Pawel Zarembski 0:01f31e923fe2 160 void USBD_Init(void)
Pawel Zarembski 0:01f31e923fe2 161 {
Pawel Zarembski 0:01f31e923fe2 162 RCC->APB1ENR |= (1 << 23); /* enable clock for USB */
Pawel Zarembski 0:01f31e923fe2 163 USBD_IntrEna(); /* Enable USB Interrupts */
Pawel Zarembski 0:01f31e923fe2 164 /* Control USB connecting via SW */
Pawel Zarembski 0:01f31e923fe2 165 USB_CONNECT_OFF();
Pawel Zarembski 0:01f31e923fe2 166 }
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168
Pawel Zarembski 0:01f31e923fe2 169 /*
Pawel Zarembski 0:01f31e923fe2 170 * USB Device Connect Function
Pawel Zarembski 0:01f31e923fe2 171 * Called by the User to Connect/Disconnect USB Device
Pawel Zarembski 0:01f31e923fe2 172 * Parameters: con: Connect/Disconnect
Pawel Zarembski 0:01f31e923fe2 173 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 174 */
Pawel Zarembski 0:01f31e923fe2 175
Pawel Zarembski 0:01f31e923fe2 176 void USBD_Connect(BOOL con)
Pawel Zarembski 0:01f31e923fe2 177 {
Pawel Zarembski 0:01f31e923fe2 178 if (con) {
Pawel Zarembski 0:01f31e923fe2 179 CNTR = CNTR_FRES; /* Force USB Reset */
Pawel Zarembski 0:01f31e923fe2 180 CNTR = 0;
Pawel Zarembski 0:01f31e923fe2 181 ISTR = 0; /* Clear Interrupt Status */
Pawel Zarembski 0:01f31e923fe2 182 CNTR = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; /* USB Interrupt Mask */
Pawel Zarembski 0:01f31e923fe2 183 USB_CONNECT_ON();
Pawel Zarembski 0:01f31e923fe2 184 } else {
Pawel Zarembski 0:01f31e923fe2 185 CNTR = CNTR_FRES | CNTR_PDWN; /* Switch Off USB Device */
Pawel Zarembski 0:01f31e923fe2 186 USB_CONNECT_OFF();
Pawel Zarembski 0:01f31e923fe2 187 }
Pawel Zarembski 0:01f31e923fe2 188 }
Pawel Zarembski 0:01f31e923fe2 189
Pawel Zarembski 0:01f31e923fe2 190
Pawel Zarembski 0:01f31e923fe2 191 /*
Pawel Zarembski 0:01f31e923fe2 192 * USB Device Reset Function
Pawel Zarembski 0:01f31e923fe2 193 * Called automatically on USB Device Reset
Pawel Zarembski 0:01f31e923fe2 194 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 195 */
Pawel Zarembski 0:01f31e923fe2 196
Pawel Zarembski 0:01f31e923fe2 197 void USBD_Reset(void)
Pawel Zarembski 0:01f31e923fe2 198 {
Pawel Zarembski 0:01f31e923fe2 199 NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
Pawel Zarembski 0:01f31e923fe2 200
Pawel Zarembski 0:01f31e923fe2 201 /* Double Buffering is not yet supported */
Pawel Zarembski 0:01f31e923fe2 202 ISTR = 0; /* Clear Interrupt Status */
Pawel Zarembski 0:01f31e923fe2 203 CNTR = CNTR_CTRM | CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM |
Pawel Zarembski 0:01f31e923fe2 204 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 205 ((USBD_RTX_DevTask != 0) ? CNTR_ERRM : 0) |
Pawel Zarembski 0:01f31e923fe2 206 ((USBD_RTX_DevTask != 0) ? CNTR_PMAOVRM : 0) |
Pawel Zarembski 0:01f31e923fe2 207 ((USBD_RTX_DevTask != 0) ? CNTR_SOFM : 0) |
Pawel Zarembski 0:01f31e923fe2 208 ((USBD_RTX_DevTask != 0) ? CNTR_ESOFM : 0);
Pawel Zarembski 0:01f31e923fe2 209 #else
Pawel Zarembski 0:01f31e923fe2 210 ((USBD_P_Error_Event != 0) ? CNTR_ERRM : 0) |
Pawel Zarembski 0:01f31e923fe2 211 ((USBD_P_Error_Event != 0) ? CNTR_PMAOVRM : 0) |
Pawel Zarembski 0:01f31e923fe2 212 ((USBD_P_SOF_Event != 0) ? CNTR_SOFM : 0) |
Pawel Zarembski 0:01f31e923fe2 213 ((USBD_P_SOF_Event != 0) ? CNTR_ESOFM : 0);
Pawel Zarembski 0:01f31e923fe2 214 #endif
Pawel Zarembski 0:01f31e923fe2 215 FreeBufAddr = EP_BUF_ADDR;
Pawel Zarembski 0:01f31e923fe2 216 BTABLE = 0x00; /* set BTABLE Address */
Pawel Zarembski 0:01f31e923fe2 217 /* Setup Control Endpoint 0 */
Pawel Zarembski 0:01f31e923fe2 218 pBUF_DSCR->ADDR_TX = FreeBufAddr;
Pawel Zarembski 0:01f31e923fe2 219 FreeBufAddr += USBD_MAX_PACKET0;
Pawel Zarembski 0:01f31e923fe2 220 pBUF_DSCR->ADDR_RX = FreeBufAddr;
Pawel Zarembski 0:01f31e923fe2 221 FreeBufAddr += USBD_MAX_PACKET0;
Pawel Zarembski 0:01f31e923fe2 222
Pawel Zarembski 0:01f31e923fe2 223 if (USBD_MAX_PACKET0 > 62) {
Pawel Zarembski 0:01f31e923fe2 224 pBUF_DSCR->COUNT_RX = ((USBD_MAX_PACKET0 << 5) - 1) | 0x8000;
Pawel Zarembski 0:01f31e923fe2 225 } else {
Pawel Zarembski 0:01f31e923fe2 226 pBUF_DSCR->COUNT_RX = USBD_MAX_PACKET0 << 9;
Pawel Zarembski 0:01f31e923fe2 227 }
Pawel Zarembski 0:01f31e923fe2 228
Pawel Zarembski 0:01f31e923fe2 229 EPxREG(0) = EP_CONTROL | EP_RX_VALID;
Pawel Zarembski 0:01f31e923fe2 230 DADDR = DADDR_EF | 0; /* Enable USB Default Address */
Pawel Zarembski 0:01f31e923fe2 231
Pawel Zarembski 0:01f31e923fe2 232 NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
Pawel Zarembski 0:01f31e923fe2 233 }
Pawel Zarembski 0:01f31e923fe2 234
Pawel Zarembski 0:01f31e923fe2 235
Pawel Zarembski 0:01f31e923fe2 236 /*
Pawel Zarembski 0:01f31e923fe2 237 * USB Device Suspend Function
Pawel Zarembski 0:01f31e923fe2 238 * Called automatically on USB Device Suspend
Pawel Zarembski 0:01f31e923fe2 239 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 240 */
Pawel Zarembski 0:01f31e923fe2 241
Pawel Zarembski 0:01f31e923fe2 242 void USBD_Suspend(void)
Pawel Zarembski 0:01f31e923fe2 243 {
Pawel Zarembski 0:01f31e923fe2 244 CNTR |= CNTR_FSUSP; /* Force Suspend */
Pawel Zarembski 0:01f31e923fe2 245 CNTR |= CNTR_LPMODE; /* Low Power Mode */
Pawel Zarembski 0:01f31e923fe2 246 }
Pawel Zarembski 0:01f31e923fe2 247
Pawel Zarembski 0:01f31e923fe2 248
Pawel Zarembski 0:01f31e923fe2 249 /*
Pawel Zarembski 0:01f31e923fe2 250 * USB Device Resume Function
Pawel Zarembski 0:01f31e923fe2 251 * Called automatically on USB Device Resume
Pawel Zarembski 0:01f31e923fe2 252 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 253 */
Pawel Zarembski 0:01f31e923fe2 254
Pawel Zarembski 0:01f31e923fe2 255 void USBD_Resume(void)
Pawel Zarembski 0:01f31e923fe2 256 {
Pawel Zarembski 0:01f31e923fe2 257 /* Performed by Hardware */
Pawel Zarembski 0:01f31e923fe2 258 }
Pawel Zarembski 0:01f31e923fe2 259
Pawel Zarembski 0:01f31e923fe2 260
Pawel Zarembski 0:01f31e923fe2 261 /*
Pawel Zarembski 0:01f31e923fe2 262 * USB Device Remote Wakeup Function
Pawel Zarembski 0:01f31e923fe2 263 * Called automatically on USB Device Remote Wakeup
Pawel Zarembski 0:01f31e923fe2 264 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 265 */
Pawel Zarembski 0:01f31e923fe2 266
Pawel Zarembski 0:01f31e923fe2 267 void USBD_WakeUp(void)
Pawel Zarembski 0:01f31e923fe2 268 {
Pawel Zarembski 0:01f31e923fe2 269 CNTR &= ~CNTR_FSUSP; /* Clear Suspend */
Pawel Zarembski 0:01f31e923fe2 270 }
Pawel Zarembski 0:01f31e923fe2 271
Pawel Zarembski 0:01f31e923fe2 272
Pawel Zarembski 0:01f31e923fe2 273 /*
Pawel Zarembski 0:01f31e923fe2 274 * USB Device Remote Wakeup Configuration Function
Pawel Zarembski 0:01f31e923fe2 275 * Parameters: cfg: Device Enable/Disable
Pawel Zarembski 0:01f31e923fe2 276 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 277 */
Pawel Zarembski 0:01f31e923fe2 278
Pawel Zarembski 0:01f31e923fe2 279 void USBD_WakeUpCfg(BOOL cfg)
Pawel Zarembski 0:01f31e923fe2 280 {
Pawel Zarembski 0:01f31e923fe2 281 /* Not needed */
Pawel Zarembski 0:01f31e923fe2 282 }
Pawel Zarembski 0:01f31e923fe2 283
Pawel Zarembski 0:01f31e923fe2 284
Pawel Zarembski 0:01f31e923fe2 285 /*
Pawel Zarembski 0:01f31e923fe2 286 * USB Device Set Address Function
Pawel Zarembski 0:01f31e923fe2 287 * Parameters: adr: USB Device Address
Pawel Zarembski 0:01f31e923fe2 288 * setup: Called in setup stage (!=0), else after status stage
Pawel Zarembski 0:01f31e923fe2 289 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 290 */
Pawel Zarembski 0:01f31e923fe2 291
Pawel Zarembski 0:01f31e923fe2 292 void USBD_SetAddress(U32 adr, U32 setup)
Pawel Zarembski 0:01f31e923fe2 293 {
Pawel Zarembski 0:01f31e923fe2 294 if (setup) {
Pawel Zarembski 0:01f31e923fe2 295 return;
Pawel Zarembski 0:01f31e923fe2 296 }
Pawel Zarembski 0:01f31e923fe2 297
Pawel Zarembski 0:01f31e923fe2 298 DADDR = DADDR_EF | adr;
Pawel Zarembski 0:01f31e923fe2 299 }
Pawel Zarembski 0:01f31e923fe2 300
Pawel Zarembski 0:01f31e923fe2 301
Pawel Zarembski 0:01f31e923fe2 302 /*
Pawel Zarembski 0:01f31e923fe2 303 * USB Device Configure Function
Pawel Zarembski 0:01f31e923fe2 304 * Parameters: cfg: Device Configure/Deconfigure
Pawel Zarembski 0:01f31e923fe2 305 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 306 */
Pawel Zarembski 0:01f31e923fe2 307
Pawel Zarembski 0:01f31e923fe2 308 void USBD_Configure(BOOL cfg)
Pawel Zarembski 0:01f31e923fe2 309 {
Pawel Zarembski 0:01f31e923fe2 310 if (cfg == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 311 FreeBufAddr = EP_BUF_ADDR;
Pawel Zarembski 0:01f31e923fe2 312 FreeBufAddr += 2 * USBD_MAX_PACKET0; /* reset Buffer address */
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 /*
Pawel Zarembski 0:01f31e923fe2 318 * Configure USB Device Endpoint according to Descriptor
Pawel Zarembski 0:01f31e923fe2 319 * Parameters: pEPD: Pointer to Device Endpoint Descriptor
Pawel Zarembski 0:01f31e923fe2 320 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 321 */
Pawel Zarembski 0:01f31e923fe2 322
Pawel Zarembski 0:01f31e923fe2 323 void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD)
Pawel Zarembski 0:01f31e923fe2 324 {
Pawel Zarembski 0:01f31e923fe2 325 /* Double Buffering is not yet supported */
Pawel Zarembski 0:01f31e923fe2 326 U32 num, val;
Pawel Zarembski 0:01f31e923fe2 327 num = pEPD->bEndpointAddress & 0x0F;
Pawel Zarembski 0:01f31e923fe2 328 val = pEPD->wMaxPacketSize;
Pawel Zarembski 0:01f31e923fe2 329
Pawel Zarembski 0:01f31e923fe2 330 if (pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) {
Pawel Zarembski 0:01f31e923fe2 331 (pBUF_DSCR + num)->ADDR_TX = FreeBufAddr;
Pawel Zarembski 0:01f31e923fe2 332 val = (val + 1) & ~1;
Pawel Zarembski 0:01f31e923fe2 333 } else {
Pawel Zarembski 0:01f31e923fe2 334 (pBUF_DSCR + num)->ADDR_RX = FreeBufAddr;
Pawel Zarembski 0:01f31e923fe2 335
Pawel Zarembski 0:01f31e923fe2 336 if (val > 62) {
Pawel Zarembski 0:01f31e923fe2 337 val = (val + 31) & ~31;
Pawel Zarembski 0:01f31e923fe2 338 (pBUF_DSCR + num)->COUNT_RX = ((val << 5) - 1) | 0x8000;
Pawel Zarembski 0:01f31e923fe2 339 } else {
Pawel Zarembski 0:01f31e923fe2 340 val = (val + 1) & ~1;
Pawel Zarembski 0:01f31e923fe2 341 (pBUF_DSCR + num)->COUNT_RX = val << 9;
Pawel Zarembski 0:01f31e923fe2 342 }
Pawel Zarembski 0:01f31e923fe2 343 }
Pawel Zarembski 0:01f31e923fe2 344
Pawel Zarembski 0:01f31e923fe2 345 FreeBufAddr += val;
Pawel Zarembski 0:01f31e923fe2 346
Pawel Zarembski 0:01f31e923fe2 347 switch (pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK) {
Pawel Zarembski 0:01f31e923fe2 348 case USB_ENDPOINT_TYPE_CONTROL:
Pawel Zarembski 0:01f31e923fe2 349 val = EP_CONTROL;
Pawel Zarembski 0:01f31e923fe2 350 break;
Pawel Zarembski 0:01f31e923fe2 351
Pawel Zarembski 0:01f31e923fe2 352 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
Pawel Zarembski 0:01f31e923fe2 353 val = EP_ISOCHRONOUS;
Pawel Zarembski 0:01f31e923fe2 354 break;
Pawel Zarembski 0:01f31e923fe2 355
Pawel Zarembski 0:01f31e923fe2 356 case USB_ENDPOINT_TYPE_BULK:
Pawel Zarembski 0:01f31e923fe2 357 val = EP_BULK;
Pawel Zarembski 0:01f31e923fe2 358
Pawel Zarembski 0:01f31e923fe2 359 if (USB_DBL_BUF_EP & (1 << num)) {
Pawel Zarembski 0:01f31e923fe2 360 val |= EP_KIND;
Pawel Zarembski 0:01f31e923fe2 361 }
Pawel Zarembski 0:01f31e923fe2 362
Pawel Zarembski 0:01f31e923fe2 363 break;
Pawel Zarembski 0:01f31e923fe2 364
Pawel Zarembski 0:01f31e923fe2 365 case USB_ENDPOINT_TYPE_INTERRUPT:
Pawel Zarembski 0:01f31e923fe2 366 val = EP_INTERRUPT;
Pawel Zarembski 0:01f31e923fe2 367 break;
Pawel Zarembski 0:01f31e923fe2 368 }
Pawel Zarembski 0:01f31e923fe2 369
Pawel Zarembski 0:01f31e923fe2 370 val |= num;
Pawel Zarembski 0:01f31e923fe2 371 EPxREG(num) = val;
Pawel Zarembski 0:01f31e923fe2 372 }
Pawel Zarembski 0:01f31e923fe2 373
Pawel Zarembski 0:01f31e923fe2 374
Pawel Zarembski 0:01f31e923fe2 375 /*
Pawel Zarembski 0:01f31e923fe2 376 * Set Direction for USB Device Control Endpoint
Pawel Zarembski 0:01f31e923fe2 377 * Parameters: dir: Out (dir == 0), In (dir <> 0)
Pawel Zarembski 0:01f31e923fe2 378 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 379 */
Pawel Zarembski 0:01f31e923fe2 380
Pawel Zarembski 0:01f31e923fe2 381 void USBD_DirCtrlEP(U32 dir)
Pawel Zarembski 0:01f31e923fe2 382 {
Pawel Zarembski 0:01f31e923fe2 383 /* Not needed */
Pawel Zarembski 0:01f31e923fe2 384 }
Pawel Zarembski 0:01f31e923fe2 385
Pawel Zarembski 0:01f31e923fe2 386
Pawel Zarembski 0:01f31e923fe2 387 /*
Pawel Zarembski 0:01f31e923fe2 388 * Enable USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 389 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 390 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 391 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 392 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 393 */
Pawel Zarembski 0:01f31e923fe2 394
Pawel Zarembski 0:01f31e923fe2 395 void USBD_EnableEP(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 396 {
Pawel Zarembski 0:01f31e923fe2 397 EP_Status(EPNum, EP_TX_NAK | EP_RX_VALID); /* EP is able to receive */
Pawel Zarembski 0:01f31e923fe2 398 }
Pawel Zarembski 0:01f31e923fe2 399
Pawel Zarembski 0:01f31e923fe2 400
Pawel Zarembski 0:01f31e923fe2 401 /*
Pawel Zarembski 0:01f31e923fe2 402 * Disable USB Endpoint
Pawel Zarembski 0:01f31e923fe2 403 * Parameters: EPNum: Endpoint Number
Pawel Zarembski 0:01f31e923fe2 404 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 405 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 406 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 407 */
Pawel Zarembski 0:01f31e923fe2 408
Pawel Zarembski 0:01f31e923fe2 409 void USBD_DisableEP(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 410 {
Pawel Zarembski 0:01f31e923fe2 411 EP_Status(EPNum, EP_TX_DIS | EP_RX_DIS);
Pawel Zarembski 0:01f31e923fe2 412 }
Pawel Zarembski 0:01f31e923fe2 413
Pawel Zarembski 0:01f31e923fe2 414
Pawel Zarembski 0:01f31e923fe2 415 /*
Pawel Zarembski 0:01f31e923fe2 416 * Reset USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 417 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 418 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 419 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 420 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 421 */
Pawel Zarembski 0:01f31e923fe2 422
Pawel Zarembski 0:01f31e923fe2 423 void USBD_ResetEP(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 424 {
Pawel Zarembski 0:01f31e923fe2 425 EP_Reset(EPNum);
Pawel Zarembski 0:01f31e923fe2 426 }
Pawel Zarembski 0:01f31e923fe2 427
Pawel Zarembski 0:01f31e923fe2 428
Pawel Zarembski 0:01f31e923fe2 429 /*
Pawel Zarembski 0:01f31e923fe2 430 * Set Stall for USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 431 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 432 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 433 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 434 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 435 */
Pawel Zarembski 0:01f31e923fe2 436
Pawel Zarembski 0:01f31e923fe2 437 void USBD_SetStallEP(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 438 {
Pawel Zarembski 0:01f31e923fe2 439 EP_Status(EPNum, EP_TX_STALL | EP_RX_STALL);
Pawel Zarembski 0:01f31e923fe2 440 }
Pawel Zarembski 0:01f31e923fe2 441
Pawel Zarembski 0:01f31e923fe2 442
Pawel Zarembski 0:01f31e923fe2 443 /*
Pawel Zarembski 0:01f31e923fe2 444 * Clear Stall for USB Device Endpoint
Pawel Zarembski 0:01f31e923fe2 445 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 446 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 447 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 448 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 449 */
Pawel Zarembski 0:01f31e923fe2 450
Pawel Zarembski 0:01f31e923fe2 451 void USBD_ClrStallEP(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 452 {
Pawel Zarembski 0:01f31e923fe2 453 EP_Reset(EPNum); /* reset DTog Bits */
Pawel Zarembski 0:01f31e923fe2 454 EP_Status(EPNum, EP_TX_VALID | EP_RX_VALID);
Pawel Zarembski 0:01f31e923fe2 455 }
Pawel Zarembski 0:01f31e923fe2 456
Pawel Zarembski 0:01f31e923fe2 457
Pawel Zarembski 0:01f31e923fe2 458 /*
Pawel Zarembski 0:01f31e923fe2 459 * Clear USB Device Endpoint Buffer
Pawel Zarembski 0:01f31e923fe2 460 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 461 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 462 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 463 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 464 */
Pawel Zarembski 0:01f31e923fe2 465
Pawel Zarembski 0:01f31e923fe2 466 void USBD_ClearEPBuf(U32 EPNum)
Pawel Zarembski 0:01f31e923fe2 467 {
Pawel Zarembski 0:01f31e923fe2 468 ;
Pawel Zarembski 0:01f31e923fe2 469 }
Pawel Zarembski 0:01f31e923fe2 470
Pawel Zarembski 0:01f31e923fe2 471
Pawel Zarembski 0:01f31e923fe2 472 /*
Pawel Zarembski 0:01f31e923fe2 473 * Read USB Device Endpoint Data
Pawel Zarembski 0:01f31e923fe2 474 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 475 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 476 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 477 * pData: Pointer to Data Buffer
Pawel Zarembski 0:01f31e923fe2 478 * Return Value: Number of bytes read
Pawel Zarembski 0:01f31e923fe2 479 */
Pawel Zarembski 0:01f31e923fe2 480
Pawel Zarembski 0:01f31e923fe2 481 U32 USBD_ReadEP(U32 EPNum, U8 *pData, U32 bufsz)
Pawel Zarembski 0:01f31e923fe2 482 {
Pawel Zarembski 0:01f31e923fe2 483 /* Double Buffering is not yet supported */
Pawel Zarembski 0:01f31e923fe2 484 U32 num, cnt, *pv, n;
Pawel Zarembski 0:01f31e923fe2 485 num = EPNum & 0x0F;
Pawel Zarembski 0:01f31e923fe2 486 pv = (U32 *)(USB_PMA_ADDR + 2 * ((pBUF_DSCR + num)->ADDR_RX));
Pawel Zarembski 0:01f31e923fe2 487 cnt = (pBUF_DSCR + num)->COUNT_RX & EP_COUNT_MASK;
Pawel Zarembski 0:01f31e923fe2 488 if (cnt > bufsz) {
Pawel Zarembski 0:01f31e923fe2 489 cnt = bufsz;
Pawel Zarembski 0:01f31e923fe2 490 }
Pawel Zarembski 0:01f31e923fe2 491
Pawel Zarembski 0:01f31e923fe2 492 for (n = 0; n < (cnt + 1) / 2; n++) {
Pawel Zarembski 0:01f31e923fe2 493 *((__packed U16 *)pData) = *pv++;
Pawel Zarembski 0:01f31e923fe2 494 pData += 2;
Pawel Zarembski 0:01f31e923fe2 495 }
Pawel Zarembski 0:01f31e923fe2 496
Pawel Zarembski 0:01f31e923fe2 497 EP_Status(EPNum, EP_RX_VALID);
Pawel Zarembski 0:01f31e923fe2 498 return (cnt);
Pawel Zarembski 0:01f31e923fe2 499 }
Pawel Zarembski 0:01f31e923fe2 500
Pawel Zarembski 0:01f31e923fe2 501
Pawel Zarembski 0:01f31e923fe2 502 /*
Pawel Zarembski 0:01f31e923fe2 503 * Write USB Device Endpoint Data
Pawel Zarembski 0:01f31e923fe2 504 * Parameters: EPNum: Device Endpoint Number
Pawel Zarembski 0:01f31e923fe2 505 * EPNum.0..3: Address
Pawel Zarembski 0:01f31e923fe2 506 * EPNum.7: Dir
Pawel Zarembski 0:01f31e923fe2 507 * pData: Pointer to Data Buffer
Pawel Zarembski 0:01f31e923fe2 508 * cnt: Number of bytes to write
Pawel Zarembski 0:01f31e923fe2 509 * Return Value: Number of bytes written
Pawel Zarembski 0:01f31e923fe2 510 */
Pawel Zarembski 0:01f31e923fe2 511
Pawel Zarembski 0:01f31e923fe2 512 U32 USBD_WriteEP(U32 EPNum, U8 *pData, U32 cnt)
Pawel Zarembski 0:01f31e923fe2 513 {
Pawel Zarembski 0:01f31e923fe2 514 /* Double Buffering is not yet supported */
Pawel Zarembski 0:01f31e923fe2 515 U32 num, *pv, n;
Pawel Zarembski 0:01f31e923fe2 516 U16 statusEP;
Pawel Zarembski 0:01f31e923fe2 517 num = EPNum & 0x0F;
Pawel Zarembski 0:01f31e923fe2 518 pv = (U32 *)(USB_PMA_ADDR + 2 * ((pBUF_DSCR + num)->ADDR_TX));
Pawel Zarembski 0:01f31e923fe2 519
Pawel Zarembski 0:01f31e923fe2 520 for (n = 0; n < (cnt + 1) / 2; n++) {
Pawel Zarembski 0:01f31e923fe2 521 *pv++ = *((__packed U16 *)pData);
Pawel Zarembski 0:01f31e923fe2 522 pData += 2;
Pawel Zarembski 0:01f31e923fe2 523 }
Pawel Zarembski 0:01f31e923fe2 524
Pawel Zarembski 0:01f31e923fe2 525 (pBUF_DSCR + num)->COUNT_TX = cnt;
Pawel Zarembski 0:01f31e923fe2 526 statusEP = EPxREG(num);
Pawel Zarembski 0:01f31e923fe2 527
Pawel Zarembski 0:01f31e923fe2 528 if ((statusEP & EP_STAT_TX) != EP_TX_STALL) {
Pawel Zarembski 0:01f31e923fe2 529 EP_Status(EPNum, EP_TX_VALID); /* do not make EP valid if stalled */
Pawel Zarembski 0:01f31e923fe2 530 }
Pawel Zarembski 0:01f31e923fe2 531
Pawel Zarembski 0:01f31e923fe2 532 return (cnt);
Pawel Zarembski 0:01f31e923fe2 533 }
Pawel Zarembski 0:01f31e923fe2 534
Pawel Zarembski 0:01f31e923fe2 535
Pawel Zarembski 0:01f31e923fe2 536 /*
Pawel Zarembski 0:01f31e923fe2 537 * Get USB Device Last Frame Number
Pawel Zarembski 0:01f31e923fe2 538 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 539 * Return Value: Frame Number
Pawel Zarembski 0:01f31e923fe2 540 */
Pawel Zarembski 0:01f31e923fe2 541
Pawel Zarembski 0:01f31e923fe2 542 U32 USBD_GetFrame(void)
Pawel Zarembski 0:01f31e923fe2 543 {
Pawel Zarembski 0:01f31e923fe2 544 return (FNR & FNR_FN);
Pawel Zarembski 0:01f31e923fe2 545 }
Pawel Zarembski 0:01f31e923fe2 546
Pawel Zarembski 0:01f31e923fe2 547
Pawel Zarembski 0:01f31e923fe2 548 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 549 U32 LastError; /* Last Error */
Pawel Zarembski 0:01f31e923fe2 550
Pawel Zarembski 0:01f31e923fe2 551 /*
Pawel Zarembski 0:01f31e923fe2 552 * Get USB Last Error Code
Pawel Zarembski 0:01f31e923fe2 553 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 554 * Return Value: Error Code
Pawel Zarembski 0:01f31e923fe2 555 */
Pawel Zarembski 0:01f31e923fe2 556
Pawel Zarembski 0:01f31e923fe2 557 U32 USBD_GetError(void)
Pawel Zarembski 0:01f31e923fe2 558 {
Pawel Zarembski 0:01f31e923fe2 559 return (LastError);
Pawel Zarembski 0:01f31e923fe2 560 }
Pawel Zarembski 0:01f31e923fe2 561 #endif
Pawel Zarembski 0:01f31e923fe2 562
Pawel Zarembski 0:01f31e923fe2 563
Pawel Zarembski 0:01f31e923fe2 564 /*
Pawel Zarembski 0:01f31e923fe2 565 * USB Device Interrupt Service Routine
Pawel Zarembski 0:01f31e923fe2 566 */
Pawel Zarembski 0:01f31e923fe2 567
Pawel Zarembski 0:01f31e923fe2 568 void USB_LP_CAN1_RX0_IRQHandler(void)
Pawel Zarembski 0:01f31e923fe2 569 {
Pawel Zarembski 0:01f31e923fe2 570 uint32_t istr;
Pawel Zarembski 0:01f31e923fe2 571 uint32_t num;
Pawel Zarembski 0:01f31e923fe2 572 uint32_t val;
Pawel Zarembski 0:01f31e923fe2 573
Pawel Zarembski 0:01f31e923fe2 574 istr = ISTR;
Pawel Zarembski 0:01f31e923fe2 575 // Zero out endpoint ID since this is read from the queue
Pawel Zarembski 0:01f31e923fe2 576 LastIstr |= istr & ~(ISTR_DIR | ISTR_EP_ID);
Pawel Zarembski 0:01f31e923fe2 577 // Clear interrupts that are pending
Pawel Zarembski 0:01f31e923fe2 578 ISTR = ~(istr & USB_ISTR_W0C_MASK);
Pawel Zarembski 0:01f31e923fe2 579 if (istr & ISTR_CTR) {
Pawel Zarembski 0:01f31e923fe2 580 while ((istr = ISTR) & ISTR_CTR) {
Pawel Zarembski 0:01f31e923fe2 581 num = istr & ISTR_EP_ID;
Pawel Zarembski 0:01f31e923fe2 582 val = EPxREG(num);
Pawel Zarembski 0:01f31e923fe2 583
Pawel Zarembski 0:01f31e923fe2 584 // Process and filter out the zero length status out endpoint to prevent
Pawel Zarembski 0:01f31e923fe2 585 // the next SETUP packet from being dropped.
Pawel Zarembski 0:01f31e923fe2 586 if ((0 == num) && (val & EP_CTR_RX) && !(val & EP_SETUP)
Pawel Zarembski 0:01f31e923fe2 587 && (0 == ((pBUF_DSCR + num)->COUNT_RX & EP_COUNT_MASK))) {
Pawel Zarembski 0:01f31e923fe2 588 if (val & EP_CTR_TX) {
Pawel Zarembski 0:01f31e923fe2 589 // Drop the RX event but not TX
Pawel Zarembski 0:01f31e923fe2 590 stat_enque((((val & VAL_MASK) & ~EP_CTR_RX) << VAL_SHIFT) |
Pawel Zarembski 0:01f31e923fe2 591 ((num & EP_NUM_MASK) << EP_NUM_SHIFT));
Pawel Zarembski 0:01f31e923fe2 592 } else {
Pawel Zarembski 0:01f31e923fe2 593 // Drop the event
Pawel Zarembski 0:01f31e923fe2 594 }
Pawel Zarembski 0:01f31e923fe2 595 } else {
Pawel Zarembski 0:01f31e923fe2 596 stat_enque(((val & VAL_MASK) << VAL_SHIFT) |
Pawel Zarembski 0:01f31e923fe2 597 ((num & EP_NUM_MASK) << EP_NUM_SHIFT));
Pawel Zarembski 0:01f31e923fe2 598 }
Pawel Zarembski 0:01f31e923fe2 599
Pawel Zarembski 0:01f31e923fe2 600
Pawel Zarembski 0:01f31e923fe2 601 if (val & EP_CTR_RX) {
Pawel Zarembski 0:01f31e923fe2 602 EPxREG(num) = EP_VAL_UNCHANGED(val) & ~EP_CTR_RX;
Pawel Zarembski 0:01f31e923fe2 603 }
Pawel Zarembski 0:01f31e923fe2 604
Pawel Zarembski 0:01f31e923fe2 605 if (val & EP_CTR_TX) {
Pawel Zarembski 0:01f31e923fe2 606 EPxREG(num) = EP_VAL_UNCHANGED(val) & ~EP_CTR_TX;
Pawel Zarembski 0:01f31e923fe2 607 }
Pawel Zarembski 0:01f31e923fe2 608 }
Pawel Zarembski 0:01f31e923fe2 609 }
Pawel Zarembski 0:01f31e923fe2 610
Pawel Zarembski 0:01f31e923fe2 611 USBD_SignalHandler();
Pawel Zarembski 0:01f31e923fe2 612 }
Pawel Zarembski 0:01f31e923fe2 613
Pawel Zarembski 0:01f31e923fe2 614 void USBD_Handler(void)
Pawel Zarembski 0:01f31e923fe2 615 {
Pawel Zarembski 0:01f31e923fe2 616 U32 istr, num, val, num_val;
Pawel Zarembski 0:01f31e923fe2 617 cortex_int_state_t state;
Pawel Zarembski 0:01f31e923fe2 618
Pawel Zarembski 0:01f31e923fe2 619 // Get ISTR
Pawel Zarembski 0:01f31e923fe2 620 state = cortex_int_get_and_disable();
Pawel Zarembski 0:01f31e923fe2 621 istr = LastIstr;
Pawel Zarembski 0:01f31e923fe2 622 LastIstr = 0;
Pawel Zarembski 0:01f31e923fe2 623 cortex_int_restore(state);
Pawel Zarembski 0:01f31e923fe2 624
Pawel Zarembski 0:01f31e923fe2 625 /* USB Reset Request */
Pawel Zarembski 0:01f31e923fe2 626 if (istr & ISTR_RESET) {
Pawel Zarembski 0:01f31e923fe2 627 USBD_Reset();
Pawel Zarembski 0:01f31e923fe2 628 usbd_reset_core();
Pawel Zarembski 0:01f31e923fe2 629 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 630
Pawel Zarembski 0:01f31e923fe2 631 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 632 isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 633 }
Pawel Zarembski 0:01f31e923fe2 634
Pawel Zarembski 0:01f31e923fe2 635 #else
Pawel Zarembski 0:01f31e923fe2 636
Pawel Zarembski 0:01f31e923fe2 637 if (USBD_P_Reset_Event) {
Pawel Zarembski 0:01f31e923fe2 638 USBD_P_Reset_Event();
Pawel Zarembski 0:01f31e923fe2 639 }
Pawel Zarembski 0:01f31e923fe2 640
Pawel Zarembski 0:01f31e923fe2 641 #endif
Pawel Zarembski 0:01f31e923fe2 642 }
Pawel Zarembski 0:01f31e923fe2 643
Pawel Zarembski 0:01f31e923fe2 644 /* USB Suspend Request */
Pawel Zarembski 0:01f31e923fe2 645 if (istr & ISTR_SUSP) {
Pawel Zarembski 0:01f31e923fe2 646 USBD_Suspend();
Pawel Zarembski 0:01f31e923fe2 647 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 648
Pawel Zarembski 0:01f31e923fe2 649 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 650 isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 651 }
Pawel Zarembski 0:01f31e923fe2 652
Pawel Zarembski 0:01f31e923fe2 653 #else
Pawel Zarembski 0:01f31e923fe2 654
Pawel Zarembski 0:01f31e923fe2 655 if (USBD_P_Suspend_Event) {
Pawel Zarembski 0:01f31e923fe2 656 USBD_P_Suspend_Event();
Pawel Zarembski 0:01f31e923fe2 657 }
Pawel Zarembski 0:01f31e923fe2 658
Pawel Zarembski 0:01f31e923fe2 659 #endif
Pawel Zarembski 0:01f31e923fe2 660 }
Pawel Zarembski 0:01f31e923fe2 661
Pawel Zarembski 0:01f31e923fe2 662 /* USB Wakeup */
Pawel Zarembski 0:01f31e923fe2 663 if (istr & ISTR_WKUP) {
Pawel Zarembski 0:01f31e923fe2 664 USBD_WakeUp();
Pawel Zarembski 0:01f31e923fe2 665 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 666
Pawel Zarembski 0:01f31e923fe2 667 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 668 isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 669 }
Pawel Zarembski 0:01f31e923fe2 670
Pawel Zarembski 0:01f31e923fe2 671 #else
Pawel Zarembski 0:01f31e923fe2 672
Pawel Zarembski 0:01f31e923fe2 673 if (USBD_P_Resume_Event) {
Pawel Zarembski 0:01f31e923fe2 674 USBD_P_Resume_Event();
Pawel Zarembski 0:01f31e923fe2 675 }
Pawel Zarembski 0:01f31e923fe2 676
Pawel Zarembski 0:01f31e923fe2 677 #endif
Pawel Zarembski 0:01f31e923fe2 678 }
Pawel Zarembski 0:01f31e923fe2 679
Pawel Zarembski 0:01f31e923fe2 680 /* Start of Frame */
Pawel Zarembski 0:01f31e923fe2 681 if (istr & ISTR_SOF) {
Pawel Zarembski 0:01f31e923fe2 682 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 683
Pawel Zarembski 0:01f31e923fe2 684 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 685 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 686 }
Pawel Zarembski 0:01f31e923fe2 687
Pawel Zarembski 0:01f31e923fe2 688 #else
Pawel Zarembski 0:01f31e923fe2 689
Pawel Zarembski 0:01f31e923fe2 690 if (USBD_P_SOF_Event) {
Pawel Zarembski 0:01f31e923fe2 691 USBD_P_SOF_Event();
Pawel Zarembski 0:01f31e923fe2 692 }
Pawel Zarembski 0:01f31e923fe2 693
Pawel Zarembski 0:01f31e923fe2 694 #endif
Pawel Zarembski 0:01f31e923fe2 695 }
Pawel Zarembski 0:01f31e923fe2 696
Pawel Zarembski 0:01f31e923fe2 697 /* PMA Over/underrun */
Pawel Zarembski 0:01f31e923fe2 698 if (istr & ISTR_PMAOVR) {
Pawel Zarembski 0:01f31e923fe2 699 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 700 LastError = 2;
Pawel Zarembski 0:01f31e923fe2 701
Pawel Zarembski 0:01f31e923fe2 702 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 703 isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 704 }
Pawel Zarembski 0:01f31e923fe2 705
Pawel Zarembski 0:01f31e923fe2 706 #else
Pawel Zarembski 0:01f31e923fe2 707
Pawel Zarembski 0:01f31e923fe2 708 if (USBD_P_Error_Event) {
Pawel Zarembski 0:01f31e923fe2 709 USBD_P_Error_Event(2);
Pawel Zarembski 0:01f31e923fe2 710 }
Pawel Zarembski 0:01f31e923fe2 711
Pawel Zarembski 0:01f31e923fe2 712 #endif
Pawel Zarembski 0:01f31e923fe2 713 }
Pawel Zarembski 0:01f31e923fe2 714
Pawel Zarembski 0:01f31e923fe2 715 /* Error: No Answer, CRC Error, Bit Stuff Error, Frame Format Error */
Pawel Zarembski 0:01f31e923fe2 716 if (istr & ISTR_ERR) {
Pawel Zarembski 0:01f31e923fe2 717 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 718 LastError = 1;
Pawel Zarembski 0:01f31e923fe2 719
Pawel Zarembski 0:01f31e923fe2 720 if (USBD_RTX_DevTask) {
Pawel Zarembski 0:01f31e923fe2 721 isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask);
Pawel Zarembski 0:01f31e923fe2 722 }
Pawel Zarembski 0:01f31e923fe2 723
Pawel Zarembski 0:01f31e923fe2 724 #else
Pawel Zarembski 0:01f31e923fe2 725
Pawel Zarembski 0:01f31e923fe2 726 if (USBD_P_Error_Event) {
Pawel Zarembski 0:01f31e923fe2 727 USBD_P_Error_Event(1);
Pawel Zarembski 0:01f31e923fe2 728 }
Pawel Zarembski 0:01f31e923fe2 729
Pawel Zarembski 0:01f31e923fe2 730 #endif
Pawel Zarembski 0:01f31e923fe2 731 }
Pawel Zarembski 0:01f31e923fe2 732
Pawel Zarembski 0:01f31e923fe2 733 /* Endpoint Interrupts */
Pawel Zarembski 0:01f31e923fe2 734 while ((istr & ISTR_CTR) && !stat_is_empty()) {
Pawel Zarembski 0:01f31e923fe2 735 num_val = stat_deque();
Pawel Zarembski 0:01f31e923fe2 736 num = (num_val >> EP_NUM_SHIFT) & EP_NUM_MASK;
Pawel Zarembski 0:01f31e923fe2 737 val = (num_val >> VAL_SHIFT) & VAL_MASK;
Pawel Zarembski 0:01f31e923fe2 738 if (val & EP_CTR_TX) {
Pawel Zarembski 0:01f31e923fe2 739 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 740
Pawel Zarembski 0:01f31e923fe2 741 if (USBD_RTX_EPTask[num]) {
Pawel Zarembski 0:01f31e923fe2 742 isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[num]);
Pawel Zarembski 0:01f31e923fe2 743 }
Pawel Zarembski 0:01f31e923fe2 744
Pawel Zarembski 0:01f31e923fe2 745 #else
Pawel Zarembski 0:01f31e923fe2 746
Pawel Zarembski 0:01f31e923fe2 747 if (USBD_P_EP[num]) {
Pawel Zarembski 0:01f31e923fe2 748 USBD_P_EP[num](USBD_EVT_IN);
Pawel Zarembski 0:01f31e923fe2 749 }
Pawel Zarembski 0:01f31e923fe2 750
Pawel Zarembski 0:01f31e923fe2 751 #endif
Pawel Zarembski 0:01f31e923fe2 752 }
Pawel Zarembski 0:01f31e923fe2 753
Pawel Zarembski 0:01f31e923fe2 754 if (val & EP_CTR_RX) {
Pawel Zarembski 0:01f31e923fe2 755 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 756
Pawel Zarembski 0:01f31e923fe2 757 if (USBD_RTX_EPTask[num]) {
Pawel Zarembski 0:01f31e923fe2 758 isr_evt_set((val & EP_SETUP) ? USBD_EVT_SETUP : USBD_EVT_OUT, USBD_RTX_EPTask[num]);
Pawel Zarembski 0:01f31e923fe2 759 }
Pawel Zarembski 0:01f31e923fe2 760
Pawel Zarembski 0:01f31e923fe2 761 #else
Pawel Zarembski 0:01f31e923fe2 762
Pawel Zarembski 0:01f31e923fe2 763 if (USBD_P_EP[num]) {
Pawel Zarembski 0:01f31e923fe2 764 USBD_P_EP[num]((val & EP_SETUP) ? USBD_EVT_SETUP : USBD_EVT_OUT);
Pawel Zarembski 0:01f31e923fe2 765 }
Pawel Zarembski 0:01f31e923fe2 766
Pawel Zarembski 0:01f31e923fe2 767 #endif
Pawel Zarembski 0:01f31e923fe2 768 }
Pawel Zarembski 0:01f31e923fe2 769 }
Pawel Zarembski 0:01f31e923fe2 770 }