Hossein Rahmani / USBDevice
Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
72:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 72:53949e6131f6 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
Kojto 72:53949e6131f6 2 *
Kojto 72:53949e6131f6 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Kojto 72:53949e6131f6 4 * and associated documentation files (the "Software"), to deal in the Software without
Kojto 72:53949e6131f6 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
Kojto 72:53949e6131f6 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
Kojto 72:53949e6131f6 7 * Software is furnished to do so, subject to the following conditions:
Kojto 72:53949e6131f6 8 *
Kojto 72:53949e6131f6 9 * The above copyright notice and this permission notice shall be included in all copies or
Kojto 72:53949e6131f6 10 * substantial portions of the Software.
Kojto 72:53949e6131f6 11 *
Kojto 72:53949e6131f6 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Kojto 72:53949e6131f6 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Kojto 72:53949e6131f6 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Kojto 72:53949e6131f6 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Kojto 72:53949e6131f6 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Kojto 72:53949e6131f6 17 */
Kojto 72:53949e6131f6 18
Kojto 72:53949e6131f6 19 #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
Kojto 72:53949e6131f6 20
Kojto 72:53949e6131f6 21 #if defined(TARGET_KSDK2_MCUS)
Kojto 72:53949e6131f6 22 #include "fsl_common.h"
Kojto 72:53949e6131f6 23 #endif
Kojto 72:53949e6131f6 24 #include "USBHAL.h"
Kojto 72:53949e6131f6 25
Kojto 72:53949e6131f6 26 USBHAL * USBHAL::instance;
Kojto 72:53949e6131f6 27
Kojto 72:53949e6131f6 28 static volatile int epComplete = 0;
Kojto 72:53949e6131f6 29
Kojto 72:53949e6131f6 30 // Convert physical endpoint number to register bit
Kojto 72:53949e6131f6 31 #define EP(endpoint) (1<<(endpoint))
Kojto 72:53949e6131f6 32
Kojto 72:53949e6131f6 33 // Convert physical to logical
Kojto 72:53949e6131f6 34 #define PHY_TO_LOG(endpoint) ((endpoint)>>1)
Kojto 72:53949e6131f6 35
Kojto 72:53949e6131f6 36 // Get endpoint direction
Kojto 72:53949e6131f6 37 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
Kojto 72:53949e6131f6 38 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
Kojto 72:53949e6131f6 39
Kojto 72:53949e6131f6 40 #define BD_OWN_MASK (1<<7)
Kojto 72:53949e6131f6 41 #define BD_DATA01_MASK (1<<6)
Kojto 72:53949e6131f6 42 #define BD_KEEP_MASK (1<<5)
Kojto 72:53949e6131f6 43 #define BD_NINC_MASK (1<<4)
Kojto 72:53949e6131f6 44 #define BD_DTS_MASK (1<<3)
Kojto 72:53949e6131f6 45 #define BD_STALL_MASK (1<<2)
Kojto 72:53949e6131f6 46
Kojto 72:53949e6131f6 47 #define TX 1
Kojto 72:53949e6131f6 48 #define RX 0
Kojto 72:53949e6131f6 49 #define ODD 0
Kojto 72:53949e6131f6 50 #define EVEN 1
Kojto 72:53949e6131f6 51 // this macro waits a physical endpoint number
Kojto 72:53949e6131f6 52 #define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 * odd)))
Kojto 72:53949e6131f6 53
Kojto 72:53949e6131f6 54 #define SETUP_TOKEN 0x0D
Kojto 72:53949e6131f6 55 #define IN_TOKEN 0x09
Kojto 72:53949e6131f6 56 #define OUT_TOKEN 0x01
Kojto 72:53949e6131f6 57 #define TOK_PID(idx) ((bdt[idx].info >> 2) & 0x0F)
Kojto 72:53949e6131f6 58
Kojto 72:53949e6131f6 59 // for each endpt: 8 bytes
Kojto 72:53949e6131f6 60 typedef struct BDT {
Kojto 72:53949e6131f6 61 uint8_t info; // BD[0:7]
Kojto 72:53949e6131f6 62 uint8_t dummy; // RSVD: BD[8:15]
Kojto 72:53949e6131f6 63 uint16_t byte_count; // BD[16:32]
Kojto 72:53949e6131f6 64 uint32_t address; // Addr
Kojto 72:53949e6131f6 65 } BDT;
Kojto 72:53949e6131f6 66
Kojto 72:53949e6131f6 67 // there are:
Kojto 72:53949e6131f6 68 // * 4 bidirectionnal endpt -> 8 physical endpt
Kojto 72:53949e6131f6 69 // * as there are ODD and EVEN buffer -> 8*2 bdt
Kojto 72:53949e6131f6 70 MBED_ALIGN(512) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2]; // 512 bytes aligned!
Kojto 72:53949e6131f6 71
Kojto 72:53949e6131f6 72 uint8_t * endpoint_buffer[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
Kojto 72:53949e6131f6 73
Kojto 72:53949e6131f6 74 static uint8_t set_addr = 0;
Kojto 72:53949e6131f6 75 static uint8_t addr = 0;
Kojto 72:53949e6131f6 76
Kojto 72:53949e6131f6 77 static uint32_t Data1 = 0x55555555;
Kojto 72:53949e6131f6 78
Kojto 72:53949e6131f6 79 static uint32_t frameNumber() {
Kojto 72:53949e6131f6 80 return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF);
Kojto 72:53949e6131f6 81 }
Kojto 72:53949e6131f6 82
Kojto 72:53949e6131f6 83 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
Kojto 72:53949e6131f6 84 return 0;
Kojto 72:53949e6131f6 85 }
Kojto 72:53949e6131f6 86
Kojto 72:53949e6131f6 87 USBHAL::USBHAL(void) {
Kojto 72:53949e6131f6 88 // Disable IRQ
Kojto 72:53949e6131f6 89 NVIC_DisableIRQ(USB0_IRQn);
Kojto 72:53949e6131f6 90
Kojto 72:53949e6131f6 91 #if (defined(FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT > 0U))
Kojto 72:53949e6131f6 92 MPU->CESR=0;
Kojto 72:53949e6131f6 93 #endif
Kojto 72:53949e6131f6 94 // fill in callback array
Kojto 72:53949e6131f6 95 epCallback[0] = &USBHAL::EP1_OUT_callback;
Kojto 72:53949e6131f6 96 epCallback[1] = &USBHAL::EP1_IN_callback;
Kojto 72:53949e6131f6 97 epCallback[2] = &USBHAL::EP2_OUT_callback;
Kojto 72:53949e6131f6 98 epCallback[3] = &USBHAL::EP2_IN_callback;
Kojto 72:53949e6131f6 99 epCallback[4] = &USBHAL::EP3_OUT_callback;
Kojto 72:53949e6131f6 100 epCallback[5] = &USBHAL::EP3_IN_callback;
Kojto 72:53949e6131f6 101 epCallback[6] = &USBHAL::EP4_OUT_callback;
Kojto 72:53949e6131f6 102 epCallback[7] = &USBHAL::EP4_IN_callback;
Kojto 72:53949e6131f6 103
Kojto 72:53949e6131f6 104 #if defined(TARGET_KL43Z) || defined(TARGET_K22F) || defined(TARGET_K64F)
Kojto 72:53949e6131f6 105 // enable USBFS clock
Kojto 72:53949e6131f6 106 CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
Kojto 72:53949e6131f6 107 #else
Kojto 72:53949e6131f6 108 // choose usb src as PLL
Kojto 72:53949e6131f6 109 SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
Kojto 72:53949e6131f6 110 SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | (1 << SIM_SOPT2_PLLFLLSEL_SHIFT));
Kojto 72:53949e6131f6 111
Kojto 72:53949e6131f6 112 // enable OTG clock
Kojto 72:53949e6131f6 113 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
Kojto 72:53949e6131f6 114 #endif
Kojto 72:53949e6131f6 115
Kojto 72:53949e6131f6 116 // Attach IRQ
Kojto 72:53949e6131f6 117 instance = this;
Kojto 72:53949e6131f6 118 NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr);
Kojto 72:53949e6131f6 119 NVIC_EnableIRQ(USB0_IRQn);
Kojto 72:53949e6131f6 120
Kojto 72:53949e6131f6 121 // USB Module Configuration
Kojto 72:53949e6131f6 122 // Set BDT Base Register
Kojto 72:53949e6131f6 123 USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8);
Kojto 72:53949e6131f6 124 USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16);
Kojto 72:53949e6131f6 125 USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24);
Kojto 72:53949e6131f6 126
Kojto 72:53949e6131f6 127 // Clear interrupt flag
Kojto 72:53949e6131f6 128 USB0->ISTAT = 0xff;
Kojto 72:53949e6131f6 129
Kojto 72:53949e6131f6 130 // USB Interrupt Enablers
Kojto 72:53949e6131f6 131 USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK |
Kojto 72:53949e6131f6 132 USB_INTEN_SOFTOKEN_MASK |
Kojto 72:53949e6131f6 133 USB_INTEN_ERROREN_MASK |
Kojto 72:53949e6131f6 134 USB_INTEN_USBRSTEN_MASK;
Kojto 72:53949e6131f6 135
Kojto 72:53949e6131f6 136 // Disable weak pull downs
Kojto 72:53949e6131f6 137 USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK);
Kojto 72:53949e6131f6 138
Kojto 72:53949e6131f6 139 USB0->USBTRC0 |= 0x40;
Kojto 72:53949e6131f6 140
Kojto 72:53949e6131f6 141 /* Allocate control endpoint buffers */
Kojto 72:53949e6131f6 142 endpoint_buffer[EP_BDT_IDX(0, TX, ODD)] = (uint8_t *)malloc(MAX_PACKET_SIZE_EP0);
Kojto 72:53949e6131f6 143 endpoint_buffer[EP_BDT_IDX(0, RX, ODD)] = (uint8_t *)malloc(MAX_PACKET_SIZE_EP0);
Kojto 72:53949e6131f6 144 }
Kojto 72:53949e6131f6 145
Kojto 72:53949e6131f6 146 USBHAL::~USBHAL(void) { }
Kojto 72:53949e6131f6 147
Kojto 72:53949e6131f6 148 void USBHAL::connect(void) {
Kojto 72:53949e6131f6 149 // enable USB
Kojto 72:53949e6131f6 150 USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
Kojto 72:53949e6131f6 151 // Pull up enable
Kojto 72:53949e6131f6 152 USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
Kojto 72:53949e6131f6 153
Kojto 72:53949e6131f6 154 // Allocate endpoint buffers; do allocate control endpoint buffers
Kojto 72:53949e6131f6 155 for (int i = 4; i < (NUMBER_OF_PHYSICAL_ENDPOINTS * 2); i++) {
Kojto 72:53949e6131f6 156 if ((i == EPISO_OUT) || (i == EPISO_IN)) {
Kojto 72:53949e6131f6 157 endpoint_buffer[i] = (uint8_t *)malloc(MAX_PACKET_SIZE_EPISO);
Kojto 72:53949e6131f6 158 } else {
Kojto 72:53949e6131f6 159 endpoint_buffer[i] = (uint8_t *)malloc(MAX_PACKET_SIZE_EPBULK);
Kojto 72:53949e6131f6 160 }
Kojto 72:53949e6131f6 161 }
Kojto 72:53949e6131f6 162 }
Kojto 72:53949e6131f6 163
Kojto 72:53949e6131f6 164 void USBHAL::disconnect(void) {
Kojto 72:53949e6131f6 165 // disable USB
Kojto 72:53949e6131f6 166 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
Kojto 72:53949e6131f6 167 // Pull up disable
Kojto 72:53949e6131f6 168 USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
Kojto 72:53949e6131f6 169
Kojto 72:53949e6131f6 170 //Free buffers if required; do not free the control endpoint buffers
Kojto 72:53949e6131f6 171 for (int i = 4; i < (NUMBER_OF_PHYSICAL_ENDPOINTS * 2); i++) {
Kojto 72:53949e6131f6 172 free(endpoint_buffer[i]);
Kojto 72:53949e6131f6 173 endpoint_buffer[i] = NULL;
Kojto 72:53949e6131f6 174 }
Kojto 72:53949e6131f6 175 }
Kojto 72:53949e6131f6 176
Kojto 72:53949e6131f6 177 void USBHAL::configureDevice(void) {
Kojto 72:53949e6131f6 178 // not needed
Kojto 72:53949e6131f6 179 }
Kojto 72:53949e6131f6 180
Kojto 72:53949e6131f6 181 void USBHAL::unconfigureDevice(void) {
Kojto 72:53949e6131f6 182 // not needed
Kojto 72:53949e6131f6 183 }
Kojto 72:53949e6131f6 184
Kojto 72:53949e6131f6 185 void USBHAL::setAddress(uint8_t address) {
Kojto 72:53949e6131f6 186 // we don't set the address now otherwise the usb controller does not ack
Kojto 72:53949e6131f6 187 // we set a flag instead
Kojto 72:53949e6131f6 188 // see usbisr when an IN token is received
Kojto 72:53949e6131f6 189 set_addr = 1;
Kojto 72:53949e6131f6 190 addr = address;
Kojto 72:53949e6131f6 191 }
Kojto 72:53949e6131f6 192
Kojto 72:53949e6131f6 193 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
Kojto 72:53949e6131f6 194 uint32_t handshake_flag = 0;
Kojto 72:53949e6131f6 195 uint8_t * buf;
Kojto 72:53949e6131f6 196
Kojto 72:53949e6131f6 197 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
Kojto 72:53949e6131f6 198 return false;
Kojto 72:53949e6131f6 199 }
Kojto 72:53949e6131f6 200
Kojto 72:53949e6131f6 201 uint32_t log_endpoint = PHY_TO_LOG(endpoint);
Kojto 72:53949e6131f6 202
Kojto 72:53949e6131f6 203 if ((flags & ISOCHRONOUS) == 0) {
Kojto 72:53949e6131f6 204 handshake_flag = USB_ENDPT_EPHSHK_MASK;
Kojto 72:53949e6131f6 205 }
Kojto 72:53949e6131f6 206
Kojto 72:53949e6131f6 207 if (IN_EP(endpoint)) {
Kojto 72:53949e6131f6 208 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0];
Kojto 72:53949e6131f6 209 } else {
Kojto 72:53949e6131f6 210 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0];
Kojto 72:53949e6131f6 211 }
Kojto 72:53949e6131f6 212
Kojto 72:53949e6131f6 213 // IN endpt -> device to host (TX)
Kojto 72:53949e6131f6 214 if (IN_EP(endpoint)) {
Kojto 72:53949e6131f6 215 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint)
Kojto 72:53949e6131f6 216 USB_ENDPT_EPTXEN_MASK; // en TX (IN) tran
Kojto 72:53949e6131f6 217 bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf;
Kojto 72:53949e6131f6 218 bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0;
Kojto 72:53949e6131f6 219 }
Kojto 72:53949e6131f6 220 // OUT endpt -> host to device (RX)
Kojto 72:53949e6131f6 221 else {
Kojto 72:53949e6131f6 222 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint)
Kojto 72:53949e6131f6 223 USB_ENDPT_EPRXEN_MASK; // en RX (OUT) tran.
Kojto 72:53949e6131f6 224 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket;
Kojto 72:53949e6131f6 225 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = (uint32_t) buf;
Kojto 72:53949e6131f6 226 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info = BD_OWN_MASK | BD_DTS_MASK;
Kojto 72:53949e6131f6 227 bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info = 0;
Kojto 72:53949e6131f6 228 }
Kojto 72:53949e6131f6 229
Kojto 72:53949e6131f6 230 Data1 |= (1 << endpoint);
Kojto 72:53949e6131f6 231
Kojto 72:53949e6131f6 232 return true;
Kojto 72:53949e6131f6 233 }
Kojto 72:53949e6131f6 234
Kojto 72:53949e6131f6 235 // read setup packet
Kojto 72:53949e6131f6 236 void USBHAL::EP0setup(uint8_t *buffer) {
Kojto 72:53949e6131f6 237 uint32_t sz;
Kojto 72:53949e6131f6 238 endpointReadResult(EP0OUT, buffer, &sz);
Kojto 72:53949e6131f6 239 }
Kojto 72:53949e6131f6 240
Kojto 72:53949e6131f6 241 void USBHAL::EP0readStage(void) {
Kojto 72:53949e6131f6 242 Data1 &= ~1UL; // set DATA0
Kojto 72:53949e6131f6 243 bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
Kojto 72:53949e6131f6 244 }
Kojto 72:53949e6131f6 245
Kojto 72:53949e6131f6 246 void USBHAL::EP0read(void) {
Kojto 72:53949e6131f6 247 uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0);
Kojto 72:53949e6131f6 248 bdt[idx].byte_count = MAX_PACKET_SIZE_EP0;
Kojto 72:53949e6131f6 249 }
Kojto 72:53949e6131f6 250
Kojto 72:53949e6131f6 251 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
Kojto 72:53949e6131f6 252 uint32_t sz;
Kojto 72:53949e6131f6 253 endpointReadResult(EP0OUT, buffer, &sz);
Kojto 72:53949e6131f6 254 return sz;
Kojto 72:53949e6131f6 255 }
Kojto 72:53949e6131f6 256
Kojto 72:53949e6131f6 257 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
Kojto 72:53949e6131f6 258 endpointWrite(EP0IN, buffer, size);
Kojto 72:53949e6131f6 259 }
Kojto 72:53949e6131f6 260
Kojto 72:53949e6131f6 261 void USBHAL::EP0getWriteResult(void) {
Kojto 72:53949e6131f6 262 }
Kojto 72:53949e6131f6 263
Kojto 72:53949e6131f6 264 void USBHAL::EP0stall(void) {
Kojto 72:53949e6131f6 265 stallEndpoint(EP0OUT);
Kojto 72:53949e6131f6 266 }
Kojto 72:53949e6131f6 267
Kojto 72:53949e6131f6 268 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
Kojto 72:53949e6131f6 269 endpoint = PHY_TO_LOG(endpoint);
Kojto 72:53949e6131f6 270 uint32_t idx = EP_BDT_IDX(endpoint, RX, 0);
Kojto 72:53949e6131f6 271 bdt[idx].byte_count = maximumSize;
Kojto 72:53949e6131f6 272 return EP_PENDING;
Kojto 72:53949e6131f6 273 }
Kojto 72:53949e6131f6 274
Kojto 72:53949e6131f6 275 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
Kojto 72:53949e6131f6 276 uint32_t n, sz, idx, setup = 0;
Kojto 72:53949e6131f6 277 uint8_t not_iso;
Kojto 72:53949e6131f6 278 uint8_t * ep_buf;
Kojto 72:53949e6131f6 279
Kojto 72:53949e6131f6 280 uint32_t log_endpoint = PHY_TO_LOG(endpoint);
Kojto 72:53949e6131f6 281
Kojto 72:53949e6131f6 282 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
Kojto 72:53949e6131f6 283 return EP_INVALID;
Kojto 72:53949e6131f6 284 }
Kojto 72:53949e6131f6 285
Kojto 72:53949e6131f6 286 // if read on a IN endpoint -> error
Kojto 72:53949e6131f6 287 if (IN_EP(endpoint)) {
Kojto 72:53949e6131f6 288 return EP_INVALID;
Kojto 72:53949e6131f6 289 }
Kojto 72:53949e6131f6 290
Kojto 72:53949e6131f6 291 idx = EP_BDT_IDX(log_endpoint, RX, 0);
Kojto 72:53949e6131f6 292 sz = bdt[idx].byte_count;
Kojto 72:53949e6131f6 293 not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK;
Kojto 72:53949e6131f6 294
Kojto 72:53949e6131f6 295 //for isochronous endpoint, we don't wait an interrupt
Kojto 72:53949e6131f6 296 if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) {
Kojto 72:53949e6131f6 297 return EP_PENDING;
Kojto 72:53949e6131f6 298 }
Kojto 72:53949e6131f6 299
Kojto 72:53949e6131f6 300 if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) {
Kojto 72:53949e6131f6 301 setup = 1;
Kojto 72:53949e6131f6 302 }
Kojto 72:53949e6131f6 303
Kojto 72:53949e6131f6 304 ep_buf = endpoint_buffer[idx];
Kojto 72:53949e6131f6 305
Kojto 72:53949e6131f6 306 for (n = 0; n < sz; n++) {
Kojto 72:53949e6131f6 307 buffer[n] = ep_buf[n];
Kojto 72:53949e6131f6 308 }
Kojto 72:53949e6131f6 309
Kojto 72:53949e6131f6 310 if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) {
Kojto 72:53949e6131f6 311 if (setup && (buffer[6] == 0)) // if no setup data stage,
Kojto 72:53949e6131f6 312 Data1 &= ~1UL; // set DATA0
Kojto 72:53949e6131f6 313 else
Kojto 72:53949e6131f6 314 Data1 ^= (1 << endpoint);
Kojto 72:53949e6131f6 315 }
Kojto 72:53949e6131f6 316
Kojto 72:53949e6131f6 317 if (((Data1 >> endpoint) & 1)) {
Kojto 72:53949e6131f6 318 bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK;
Kojto 72:53949e6131f6 319 }
Kojto 72:53949e6131f6 320 else {
Kojto 72:53949e6131f6 321 bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK;
Kojto 72:53949e6131f6 322 }
Kojto 72:53949e6131f6 323
Kojto 72:53949e6131f6 324 USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
Kojto 72:53949e6131f6 325 *bytesRead = sz;
Kojto 72:53949e6131f6 326
Kojto 72:53949e6131f6 327 epComplete &= ~EP(endpoint);
Kojto 72:53949e6131f6 328 return EP_COMPLETED;
Kojto 72:53949e6131f6 329 }
Kojto 72:53949e6131f6 330
Kojto 72:53949e6131f6 331 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
Kojto 72:53949e6131f6 332 uint32_t idx, n;
Kojto 72:53949e6131f6 333 uint8_t * ep_buf;
Kojto 72:53949e6131f6 334
Kojto 72:53949e6131f6 335 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) {
Kojto 72:53949e6131f6 336 return EP_INVALID;
Kojto 72:53949e6131f6 337 }
Kojto 72:53949e6131f6 338
Kojto 72:53949e6131f6 339 // if write on a OUT endpoint -> error
Kojto 72:53949e6131f6 340 if (OUT_EP(endpoint)) {
Kojto 72:53949e6131f6 341 return EP_INVALID;
Kojto 72:53949e6131f6 342 }
Kojto 72:53949e6131f6 343
Kojto 72:53949e6131f6 344 idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0);
Kojto 72:53949e6131f6 345 bdt[idx].byte_count = size;
Kojto 72:53949e6131f6 346
Kojto 72:53949e6131f6 347 ep_buf = endpoint_buffer[idx];
Kojto 72:53949e6131f6 348
Kojto 72:53949e6131f6 349 for (n = 0; n < size; n++) {
Kojto 72:53949e6131f6 350 ep_buf[n] = data[n];
Kojto 72:53949e6131f6 351 }
Kojto 72:53949e6131f6 352
Kojto 72:53949e6131f6 353 if ((Data1 >> endpoint) & 1) {
Kojto 72:53949e6131f6 354 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
Kojto 72:53949e6131f6 355 } else {
Kojto 72:53949e6131f6 356 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK;
Kojto 72:53949e6131f6 357 }
Kojto 72:53949e6131f6 358
Kojto 72:53949e6131f6 359 Data1 ^= (1 << endpoint);
Kojto 72:53949e6131f6 360
Kojto 72:53949e6131f6 361 return EP_PENDING;
Kojto 72:53949e6131f6 362 }
Kojto 72:53949e6131f6 363
Kojto 72:53949e6131f6 364 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
Kojto 72:53949e6131f6 365 if (epComplete & EP(endpoint)) {
Kojto 72:53949e6131f6 366 epComplete &= ~EP(endpoint);
Kojto 72:53949e6131f6 367 return EP_COMPLETED;
Kojto 72:53949e6131f6 368 }
Kojto 72:53949e6131f6 369
Kojto 72:53949e6131f6 370 return EP_PENDING;
Kojto 72:53949e6131f6 371 }
Kojto 72:53949e6131f6 372
Kojto 72:53949e6131f6 373 void USBHAL::stallEndpoint(uint8_t endpoint) {
Kojto 72:53949e6131f6 374 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
Kojto 72:53949e6131f6 375 }
Kojto 72:53949e6131f6 376
Kojto 72:53949e6131f6 377 void USBHAL::unstallEndpoint(uint8_t endpoint) {
Kojto 72:53949e6131f6 378 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
Kojto 72:53949e6131f6 379 }
Kojto 72:53949e6131f6 380
Kojto 72:53949e6131f6 381 bool USBHAL::getEndpointStallState(uint8_t endpoint) {
Kojto 72:53949e6131f6 382 uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK);
Kojto 72:53949e6131f6 383 return (stall) ? true : false;
Kojto 72:53949e6131f6 384 }
Kojto 72:53949e6131f6 385
Kojto 72:53949e6131f6 386 void USBHAL::remoteWakeup(void) {
Kojto 72:53949e6131f6 387 // [TODO]
Kojto 72:53949e6131f6 388 }
Kojto 72:53949e6131f6 389
Kojto 72:53949e6131f6 390
Kojto 72:53949e6131f6 391 void USBHAL::_usbisr(void) {
Kojto 72:53949e6131f6 392 instance->usbisr();
Kojto 72:53949e6131f6 393 }
Kojto 72:53949e6131f6 394
Kojto 72:53949e6131f6 395
Kojto 72:53949e6131f6 396 void USBHAL::usbisr(void) {
Kojto 72:53949e6131f6 397 uint8_t i;
Kojto 72:53949e6131f6 398 uint8_t istat = USB0->ISTAT;
Kojto 72:53949e6131f6 399
Kojto 72:53949e6131f6 400 // reset interrupt
Kojto 72:53949e6131f6 401 if (istat & USB_ISTAT_USBRST_MASK) {
Kojto 72:53949e6131f6 402 // disable all endpt
Kojto 72:53949e6131f6 403 for(i = 0; i < 16; i++) {
Kojto 72:53949e6131f6 404 USB0->ENDPOINT[i].ENDPT = 0x00;
Kojto 72:53949e6131f6 405 }
Kojto 72:53949e6131f6 406
Kojto 72:53949e6131f6 407 // enable control endpoint
Kojto 72:53949e6131f6 408 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
Kojto 72:53949e6131f6 409 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
Kojto 72:53949e6131f6 410
Kojto 72:53949e6131f6 411 Data1 = 0x55555555;
Kojto 72:53949e6131f6 412 USB0->CTL |= USB_CTL_ODDRST_MASK;
Kojto 72:53949e6131f6 413
Kojto 72:53949e6131f6 414 USB0->ISTAT = 0xFF; // clear all interrupt status flags
Kojto 72:53949e6131f6 415 USB0->ERRSTAT = 0xFF; // clear all error flags
Kojto 72:53949e6131f6 416 USB0->ERREN = 0xFF; // enable error interrupt sources
Kojto 72:53949e6131f6 417 USB0->ADDR = 0x00; // set default address
Kojto 72:53949e6131f6 418
Kojto 72:53949e6131f6 419 // reset bus for USBDevice layer
Kojto 72:53949e6131f6 420 busReset();
Kojto 72:53949e6131f6 421
Kojto 72:53949e6131f6 422 return;
Kojto 72:53949e6131f6 423 }
Kojto 72:53949e6131f6 424
Kojto 72:53949e6131f6 425 // resume interrupt
Kojto 72:53949e6131f6 426 if (istat & USB_ISTAT_RESUME_MASK) {
Kojto 72:53949e6131f6 427 USB0->ISTAT = USB_ISTAT_RESUME_MASK;
Kojto 72:53949e6131f6 428 }
Kojto 72:53949e6131f6 429
Kojto 72:53949e6131f6 430 // SOF interrupt
Kojto 72:53949e6131f6 431 if (istat & USB_ISTAT_SOFTOK_MASK) {
Kojto 72:53949e6131f6 432 USB0->ISTAT = USB_ISTAT_SOFTOK_MASK;
Kojto 72:53949e6131f6 433 // SOF event, read frame number
Kojto 72:53949e6131f6 434 SOF(frameNumber());
Kojto 72:53949e6131f6 435 }
Kojto 72:53949e6131f6 436
Kojto 72:53949e6131f6 437 // stall interrupt
Kojto 72:53949e6131f6 438 if (istat & 1<<7) {
Kojto 72:53949e6131f6 439 if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK)
Kojto 72:53949e6131f6 440 USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
Kojto 72:53949e6131f6 441 USB0->ISTAT |= USB_ISTAT_STALL_MASK;
Kojto 72:53949e6131f6 442 }
Kojto 72:53949e6131f6 443
Kojto 72:53949e6131f6 444 // token interrupt
Kojto 72:53949e6131f6 445 if (istat & 1<<3) {
Kojto 72:53949e6131f6 446 uint32_t num = (USB0->STAT >> 4) & 0x0F;
Kojto 72:53949e6131f6 447 uint32_t dir = (USB0->STAT >> 3) & 0x01;
Kojto 72:53949e6131f6 448 uint32_t ev_odd = (USB0->STAT >> 2) & 0x01;
Kojto 72:53949e6131f6 449 int endpoint = (num << 1) | dir;
Kojto 72:53949e6131f6 450
Kojto 72:53949e6131f6 451 // setup packet
Kojto 72:53949e6131f6 452 if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) {
Kojto 72:53949e6131f6 453 Data1 &= ~0x02;
Kojto 72:53949e6131f6 454 bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
Kojto 72:53949e6131f6 455 bdt[EP_BDT_IDX(0, TX, ODD)].info &= ~BD_OWN_MASK;
Kojto 72:53949e6131f6 456
Kojto 72:53949e6131f6 457 // EP0 SETUP event (SETUP data received)
Kojto 72:53949e6131f6 458 EP0setupCallback();
Kojto 72:53949e6131f6 459
Kojto 72:53949e6131f6 460 } else {
Kojto 72:53949e6131f6 461 // OUT packet
Kojto 72:53949e6131f6 462 if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) {
Kojto 72:53949e6131f6 463 if (num == 0)
Kojto 72:53949e6131f6 464 EP0out();
Kojto 72:53949e6131f6 465 else {
Kojto 72:53949e6131f6 466 epComplete |= EP(endpoint);
Kojto 72:53949e6131f6 467 if ((instance->*(epCallback[endpoint - 2]))()) {
Kojto 72:53949e6131f6 468 epComplete &= ~EP(endpoint);
Kojto 72:53949e6131f6 469 }
Kojto 72:53949e6131f6 470 }
Kojto 72:53949e6131f6 471 }
Kojto 72:53949e6131f6 472
Kojto 72:53949e6131f6 473 // IN packet
Kojto 72:53949e6131f6 474 if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) {
Kojto 72:53949e6131f6 475 if (num == 0) {
Kojto 72:53949e6131f6 476 EP0in();
Kojto 72:53949e6131f6 477 if (set_addr == 1) {
Kojto 72:53949e6131f6 478 USB0->ADDR = addr & 0x7F;
Kojto 72:53949e6131f6 479 set_addr = 0;
Kojto 72:53949e6131f6 480 }
Kojto 72:53949e6131f6 481 }
Kojto 72:53949e6131f6 482 else {
Kojto 72:53949e6131f6 483 epComplete |= EP(endpoint);
Kojto 72:53949e6131f6 484 if ((instance->*(epCallback[endpoint - 2]))()) {
Kojto 72:53949e6131f6 485 epComplete &= ~EP(endpoint);
Kojto 72:53949e6131f6 486 }
Kojto 72:53949e6131f6 487 }
Kojto 72:53949e6131f6 488 }
Kojto 72:53949e6131f6 489 }
Kojto 72:53949e6131f6 490
Kojto 72:53949e6131f6 491 USB0->ISTAT = USB_ISTAT_TOKDNE_MASK;
Kojto 72:53949e6131f6 492 }
Kojto 72:53949e6131f6 493
Kojto 72:53949e6131f6 494 // sleep interrupt
Kojto 72:53949e6131f6 495 if (istat & 1<<4) {
Kojto 72:53949e6131f6 496 USB0->ISTAT |= USB_ISTAT_SLEEP_MASK;
Kojto 72:53949e6131f6 497 }
Kojto 72:53949e6131f6 498
Kojto 72:53949e6131f6 499 // error interrupt
Kojto 72:53949e6131f6 500 if (istat & USB_ISTAT_ERROR_MASK) {
Kojto 72:53949e6131f6 501 USB0->ERRSTAT = 0xFF;
Kojto 72:53949e6131f6 502 USB0->ISTAT |= USB_ISTAT_ERROR_MASK;
Kojto 72:53949e6131f6 503 }
Kojto 72:53949e6131f6 504 }
Kojto 72:53949e6131f6 505
Kojto 72:53949e6131f6 506
Kojto 72:53949e6131f6 507 #endif