Changeset 224 for rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c
- Timestamp:
- Apr 30, 2016, 11:29:25 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c
r136 r224 1 /* ---------------------------------------------------------------------------- 2 * SAM Software Package License 3 * ---------------------------------------------------------------------------- 4 * Copyright (c) 2011-2012, Atmel Corporation 5 * 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following condition is met: 10 * 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the disclaimer below. 13 * 14 * Atmel's name may not be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * ---------------------------------------------------------------------------- 28 */ 1 /* 2 Copyright (c) 2014 Arduino LLC. All right reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 See the GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 /* 19 ** Modified 04/04/2016 by Arduino.org development team 20 */ 21 22 29 23 30 24 #include <stdio.h> 25 #include <stdint.h> 26 #include <string.h> 27 28 #include "../Arduino.h" 29 #include "variant.h" 30 #include "USB_host.h" 31 #include "samd21_host.h" 32 #include "sam.h" 33 #include "wiring_digital.h" 34 #include "wiring_private.h" 35 36 #define HOST_DEFINED 31 37 32 38 #ifdef HOST_DEFINED … … 35 41 #define TRACE_UOTGHS_HOST(x) 36 42 37 //extern void (*gpf_isr)(void);38 39 43 // Handle UOTGHS Host driver state 40 44 static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS; 41 45 42 __attribute__((__aligned__(4))) UsbHostDescriptor usb_pipe_table[USB_EPT_NUM]; 46 __attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM]; 47 48 extern void (*gpf_isr)(void); 43 49 44 50 45 51 // NVM Software Calibration Area Mapping 46 52 // USB TRANSN calibration value. Should be written to the USB PADCAL register. 47 #define NVM_USB_PAD_TRANSN_POS 4548 #define NVM_USB_PAD_TRANSN_SIZE 553 #define NVM_USB_PAD_TRANSN_POS 45 54 #define NVM_USB_PAD_TRANSN_SIZE 5 49 55 // USB TRANSP calibration value. Should be written to the USB PADCAL register. 50 #define NVM_USB_PAD_TRANSP_POS 5051 #define NVM_USB_PAD_TRANSP_SIZE 556 #define NVM_USB_PAD_TRANSP_POS 50 57 #define NVM_USB_PAD_TRANSP_SIZE 5 52 58 // USB TRIM calibration value. Should be written to the USB PADCAL register. 53 #define NVM_USB_PAD_TRIM_POS 55 54 #define NVM_USB_PAD_TRIM_SIZE 3 59 #define NVM_USB_PAD_TRIM_POS 55 60 #define NVM_USB_PAD_TRIM_SIZE 3 61 62 static void UHD_ISR(void); 55 63 56 64 /** … … 60 68 { 61 69 uint32_t pad_transn; 62 uint32_t pad_transp; 63 uint32_t pad_trim; 70 uint32_t pad_transp; 71 uint32_t pad_trim; 72 uint32_t i; 73 74 // USB_SetHandler(&USB_Handler); 75 USB_SetHandler(&UHD_ISR); 64 76 65 77 /* Enable USB clock */ 66 78 PM->APBBMASK.reg |= PM_APBBMASK_USB; 67 79 68 /* Set up the USB DP/DN pins */ 69 PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; 70 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); 71 PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u)); 72 PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1; 73 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); 74 PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); 80 /* Set up the USB DP/DM pins */ 81 pinPeripheral( 33ul, PIO_COM ); 82 pinPeripheral( 34ul, PIO_COM ); 75 83 76 84 /* ---------------------------------------------------------------------------------------------- 77 78 79 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) |// Generic Clock Multiplexer 680 GCLK_CLKCTRL_GEN_GCLK0 |// Generic Clock Generator 0 is source81 GCLK_CLKCTRL_CLKEN;82 83 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY)84 { 85 /* Wait for synchronization */85 * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) 86 */ 87 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6 88 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 89 GCLK_CLKCTRL_CLKEN; 90 91 while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) 92 { 93 /* Wait for synchronization */ 86 94 } 87 95 88 96 /* Reset */ 89 97 USB->HOST.CTRLA.bit.SWRST = 1; 90 while (USB->HOST.SYNCBUSY.bit.SWRST) { 98 while (USB->HOST.SYNCBUSY.bit.SWRST) 99 { 91 100 /* Sync wait */ 92 101 } 93 102 94 udd_enable(); 103 // uhd_enable(); 104 USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE | USB_CTRLA_MODE; 105 uhd_force_host_mode(); 106 while (USB->HOST.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE); 95 107 96 108 /* Load Pad Calibration */ 97 pad_transn =( *((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller 98 + (NVM_USB_PAD_TRANSN_POS / 32)) 99 >> (NVM_USB_PAD_TRANSN_POS % 32)) 100 & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); 101 102 if (pad_transn == 0x1F) { // maximum value (31) 109 pad_transn = (*((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller 110 + (NVM_USB_PAD_TRANSN_POS / 32)) 111 >> (NVM_USB_PAD_TRANSN_POS % 32)) 112 & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); 113 114 if (pad_transn == 0x1F) // maximum value (31) 115 { 103 116 pad_transn = 5; 104 117 } … … 106 119 USB->HOST.PADCAL.bit.TRANSN = pad_transn; 107 120 108 pad_transp =( *((uint32_t *)(NVMCTRL_OTP4) 109 + (NVM_USB_PAD_TRANSP_POS / 32)) 110 >> (NVM_USB_PAD_TRANSP_POS % 32)) 111 & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); 112 113 if (pad_transp == 0x1F) { // maximum value (31) 121 pad_transp = (*((uint32_t *)(NVMCTRL_OTP4) 122 + (NVM_USB_PAD_TRANSP_POS / 32)) 123 >> (NVM_USB_PAD_TRANSP_POS % 32)) 124 & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); 125 126 if (pad_transp == 0x1F) // maximum value (31) 127 { 114 128 pad_transp = 29; 115 129 } … … 117 131 USB->HOST.PADCAL.bit.TRANSP = pad_transp; 118 132 119 pad_trim =( *((uint32_t *)(NVMCTRL_OTP4) 120 + (NVM_USB_PAD_TRIM_POS / 32)) 121 >> (NVM_USB_PAD_TRIM_POS % 32)) 122 & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); 123 124 if (pad_trim == 0x7) { // maximum value (7) 133 pad_trim = (*((uint32_t *)(NVMCTRL_OTP4) 134 + (NVM_USB_PAD_TRIM_POS / 32)) 135 >> (NVM_USB_PAD_TRIM_POS % 32)) 136 & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); 137 138 if (pad_trim == 0x7) // maximum value (7) 139 { 125 140 pad_trim = 3; 126 141 } … … 128 143 USB->HOST.PADCAL.bit.TRIM = pad_trim; 129 144 145 130 146 /* Set the configuration */ 131 u dd_force_host_mode();132 udd_device_run_in_standby();133 // Set address of USB SRAM 134 USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]);135 // For USB_SPEED_FULL136 udd_force_full_speed();137 for (uint32_t i = 0; i < sizeof(usb_endpoint_table); i++){138 (*(uint32_t *)(&usb_endpoint_table[0]+i)) = 0;139 147 uhd_run_in_standby(); 148 // Set address of USB SRAM 149 USB->HOST.DESCADD.reg = (uint32_t)(&usb_pipe_table[0]); 150 // For USB_SPEED_FULL 151 uhd_force_full_speed(); 152 for (i = 0; i < sizeof(usb_pipe_table); i++) 153 { 154 (*(uint32_t *)(&usb_pipe_table[0] + i)) = 0; 155 } 140 156 141 157 uhd_state = UHD_STATE_NO_VBUS; 142 158 159 // Put VBUS on USB port 160 pinMode( 32ul, OUTPUT ); 161 digitalWrite( 32ul, HIGH ); 162 163 uhd_enable_connection_int(); 164 165 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DCONN; 166 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_WAKEUP; 167 USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DDISC; 168 143 169 USB->HOST.CTRLB.bit.VBUSOK = 1; 144 170 145 171 // Configure interrupts 146 NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); 147 NVIC_EnableIRQ((IRQn_Type) USB_IRQn); 148 } 149 150 //static void UHD_ISR(void) 151 void USB_Handler(void) 152 { 153 uint16_t flags; 154 uint8_t i; 155 uint8_t ept_int; 156 157 ept_int = udd_endpoint_interrupt(); 158 159 /* Not endpoint interrupt */ 160 if (0 == ept_int) 161 { 162 163 164 } 165 else 166 { 167 /* host interrupts */ 172 NVIC_SetPriority((IRQn_Type)USB_IRQn, 0UL); 173 NVIC_EnableIRQ((IRQn_Type)USB_IRQn); 174 } 175 176 177 static void UHD_ISR(void) 178 //void USB_Handler(void) 179 { 180 uint16_t flags; 181 182 if (USB->HOST.CTRLA.bit.MODE) { 183 /*host mode ISR */ 168 184 169 185 /* get interrupt flags */ … … 171 187 172 188 /* host SOF interrupt */ 173 if (flags & USB_HOST_INTFLAG_HSOF) { 189 if (flags & USB_HOST_INTFLAG_HSOF) 190 { 174 191 /* clear the flag */ 175 192 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_HSOF; 176 uhd_state = UHD_STATE_CONNECTED;193 uhd_state = UHD_STATE_CONNECTED; 177 194 return; 178 195 } 179 196 180 197 /* host reset interrupt */ 181 if (flags & USB_HOST_INTFLAG_RST) { 198 if (flags & USB_HOST_INTFLAG_RST) 199 { 182 200 /* clear the flag */ 183 201 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST; 184 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;202 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 185 203 return; 186 204 } 187 205 188 206 /* host upstream resume interrupts */ 189 if (flags & USB_HOST_INTFLAG_UPRSM) { 207 if (flags & USB_HOST_INTFLAG_UPRSM) 208 { 190 209 /* clear the flags */ 191 210 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_UPRSM; 192 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;211 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 193 212 return; 194 213 } 195 214 196 215 /* host downstream resume interrupts */ 197 if (flags & USB_HOST_INTFLAG_DNRSM) { 216 if (flags & USB_HOST_INTFLAG_DNRSM) 217 { 198 218 /* clear the flags */ 199 219 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DNRSM; 200 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;220 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 201 221 return; 202 222 } 203 223 204 224 /* host wakeup interrupts */ 205 if (flags & USB_HOST_INTFLAG_WAKEUP) { 225 if (flags & USB_HOST_INTFLAG_WAKEUP) 226 { 206 227 /* clear the flags */ 207 228 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_WAKEUP; 208 uhd_state = UHD_STATE_CONNECTED;//UHD_STATE_ERROR;229 uhd_state = UHD_STATE_CONNECTED; //UHD_STATE_ERROR; 209 230 return; 210 231 } 211 232 212 233 /* host ram access interrupt */ 213 if (flags & USB_HOST_INTFLAG_RAMACER) { 234 if (flags & USB_HOST_INTFLAG_RAMACER) 235 { 214 236 /* clear the flag */ 215 237 USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RAMACER; 216 uhd_state = UHD_STATE_DISCONNECTED;//UHD_STATE_ERROR;238 uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR; 217 239 return; 218 240 } 219 241 220 242 /* host connect interrupt */ 221 if (flags & USB_HOST_INTFLAG_DCONN) { 222 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");) 243 if (flags & USB_HOST_INTFLAG_DCONN) 244 { 245 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n"); 246 ) 223 247 /* clear the flag */ 224 248 uhd_ack_connection(); … … 231 255 } 232 256 233 /* host disconnect interrupt */ 234 if (flags & USB_HOST_INTFLAG_DDISC) { 235 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");) 257 /* host disconnect interrupt */ 258 if (flags & USB_HOST_INTFLAG_DDISC) 259 { 260 TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n"); 261 ) 236 262 /* clear the flag */ 237 263 uhd_ack_disconnection(); … … 246 272 return; 247 273 } 248 249 } 250 251 } 252 253 254 255 256 /** 257 * \brief Trigger a USB bus reset. 258 */ 259 void UHD_BusReset(void) 260 { 261 USB->HOST.CTRLB.bit.BUSRESET = 1;; 262 } 274 } 275 else { 276 while(1); 277 } 278 } 279 280 263 281 264 282 /** … … 269 287 uhd_vbus_state_t UHD_GetVBUSState(void) 270 288 { 271 return uhd_state; 272 } 273 289 return uhd_state; 290 } 274 291 275 292 … … 283 300 * \retval 1 error. 284 301 */ 285 uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size) 286 { 287 struct usb_host_pipe_config cfg; 288 289 if (ep_size < 8) 290 { 291 return 0; 292 } 293 294 /* set pipe config */ 295 USB->HOST.HostPipe[0].PCFG.bit.BK = 0; 296 USB->HOST.HostPipe[0].PCFG.bit.PTYPE = USB_HOST_PIPE_TYPE_CONTROL; 297 USB->HOST.HostPipe[0].BINTERVAL.reg = 0; 298 USB->HOST.HostPipe[0].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_SETUP; 299 300 memset((uint8_t *)&usb_pipe_table[pipe_num], 0, sizeof(usb_pipe_table[0])); 301 usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PDADDR = 0; 302 usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0; 303 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03; // 64 bytes 304 305 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; 306 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR; 307 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TXSTP; 308 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL; 309 310 return 1; 311 } 302 uint32_t UHD_Pipe0_Alloc(uint32_t ul_add , uint32_t ul_ep_size) 303 { 304 (void)(ul_add); // Unused argument 305 306 if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) ) 307 ul_ep_size = USB_PCKSIZE_SIZE_8_BYTES; // Low Speed 308 else 309 ul_ep_size = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed 310 311 USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL; 312 usb_pipe_table[0].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0; 313 usb_pipe_table[0].HostDescBank[0].PCKSIZE.bit.SIZE = ul_ep_size; 314 315 return 0; 316 } 317 312 318 313 319 /** … … 336 342 { 337 343 /* set pipe config */ 338 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK = ul_nb_bank; 339 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTYPE = ul_type; 340 USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg = ul_interval; 341 342 if (ul_dir & USB_EP_DIR_IN) 343 { 344 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN; 345 USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 346 } 344 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK = ul_nb_bank; 345 USB->HOST.HostPipe[ul_dev_ep].PCFG.reg &= ~USB_HOST_PCFG_MASK; // USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL; 346 USB->HOST.HostPipe[ul_dev_ep].PCFG.reg |= ul_type; 347 USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg = ul_interval; 348 349 if (ul_dir & USB_EP_DIR_IN) 350 { 351 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN; 352 USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 353 } 354 else 355 { 356 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_OUT; 357 USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 358 } 359 360 if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) ) 361 ul_maxsize = USB_PCKSIZE_SIZE_8_BYTES; // Low Speed 347 362 else 348 { 349 USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT; 350 USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 351 } 352 353 memset((uint8_t *)&usb_descriptor_table.usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep])); 354 355 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr; 356 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep; 357 usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03; // 64 bytes 358 359 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk; 360 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR; 361 USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL; 362 363 return 1; 364 } 365 363 ul_maxsize = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed 364 365 memset((uint8_t *)&usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep])); 366 367 usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr; 368 usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep; 369 usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE = ul_maxsize; 370 371 return 1; 372 } 373 374 375 void UHD_Pipe_CountZero(uint32_t ul_pipe) 376 { 377 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 378 } 366 379 367 380 /** … … 372 385 void UHD_Pipe_Free(uint32_t ul_pipe) 373 386 { 374 // Unalloc pipe 375 uhd_disable_pipe(ul_pipe); 376 uhd_unallocate_memory(ul_pipe); 377 uhd_reset_pipe(ul_pipe); 378 379 // The Pipe is frozen and no additional requests will be sent to the device on this pipe address. 380 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 381 } 387 // The Pipe is frozen and no additional requests will be sent to the device on this pipe address. 388 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 389 } 390 382 391 383 392 /** … … 390 399 * \return number of data read. 391 400 */ 392 uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t* buf) 393 { 394 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE) 395 { 396 return 0; 397 } 398 399 /* get pipe config from setting register */ 400 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 401 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 402 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size; 403 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN; 404 405 /* Start transfer */ 406 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 407 408 // Unfreeze pipe 409 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 410 411 return buf_size; 412 } 401 uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t *buf) 402 { 403 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PTYPE_DIS) 404 { 405 return 0; 406 } 407 408 /* get pipe config from setting register */ 409 usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 410 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; 411 usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size; 412 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN; 413 414 /* Start transfer */ 415 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 416 417 // Unfreeze pipe 418 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 419 420 return buf_size; 421 } 422 413 423 414 424 /** … … 419 429 * \param data Buffer containing data to write. 420 430 */ 421 void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data) 422 { 423 424 if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE) 425 { 426 return 0; 427 } 428 429 /* get pipe config from setting register */ 430 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf; 431 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = buf_size; 432 usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 433 USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT; 434 435 436 return 1; 431 void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t *buf) 432 { 433 /* get pipe config from setting register */ 434 usb_pipe_table[ul_pipe].HostDescBank[0].ADDR.reg = (uint32_t)buf; 435 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = ul_size; 436 usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; 437 437 } 438 438 … … 445 445 void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type) 446 446 { 447 /* Start transfer */ 448 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 449 447 USB->HOST.HostPipe[ul_pipe].PCFG.bit.PTOKEN = ul_token_type; 448 449 /* Start transfer */ 450 if(ul_token_type == USB_HOST_PCFG_PTOKEN_SETUP ) 451 { 452 USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TXSTP; 453 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 454 } 455 else if(ul_token_type == USB_HOST_PCFG_PTOKEN_IN ) 456 { 457 USB->HOST.HostPipe[ul_pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY; 458 } 459 else 460 { 461 USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT(1); // Transfer Complete 0 462 USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY; 463 } 464 450 465 // Unfreeze pipe 451 USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE; 452 } 466 uhd_unfreeze_pipe(ul_pipe); 467 } 468 469 #define USB_HOST_PINTFLAG_TRCPT_Pos 0 /**< \brief (USB_HOST_PINTFLAG) Transfer Complete 0/1 Interrupt Flag */ 470 #define USB_HOST_PINTFLAG_TRCPT_Msk (0x3u << USB_HOST_PINTFLAG_TRCPT_Pos) 471 #define USB_HOST_PINTFLAG_TRCPT(value) ((USB_HOST_PINTFLAG_TRCPT_Msk & ((value) << USB_HOST_PINTFLAG_TRCPT_Pos))) 453 472 454 473 /** … … 463 482 uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type) 464 483 { 465 466 // Freeze pipe 467 USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE; 468 switch(uhd_ctrl_request_phase) { 469 case UHD_CTRL_REQ_PHASE_DATA_IN: 470 _uhd_ctrl_phase_data_in(p_callback_para->transfered_size); 471 break; 472 case UHD_CTRL_REQ_PHASE_ZLP_IN: 473 _uhd_ctrl_request_end(UHD_TRANS_NOERROR); 474 break; 475 case UHD_CTRL_REQ_PHASE_DATA_OUT: 476 _uhd_ctrl_phase_data_out(); 477 break; 478 case UHD_CTRL_REQ_PHASE_ZLP_OUT: 479 _uhd_ctrl_request_end(UHD_TRANS_NOERROR); 480 break; 481 } 482 return 0; 483 } 484 485 #endif 486 484 // Check for transfer completion depending on token type 485 switch (ul_token_type) 486 { 487 case USB_HOST_PCFG_PTOKEN_SETUP: 488 if (Is_uhd_setup_ready(ul_pipe)) 489 { 490 uhd_ack_setup_ready(ul_pipe); 491 uhd_freeze_pipe(ul_pipe); 492 return 1; 493 } 494 break; 495 496 case USB_HOST_PCFG_PTOKEN_IN: 497 if (Is_uhd_in_received(ul_pipe)) 498 { 499 // IN packet received 500 uhd_ack_in_received(ul_pipe); 501 // Freeze will stop after the transfer 502 uhd_freeze_pipe(ul_pipe); 503 return 1; 504 } 505 break; 506 507 case USB_HOST_PCFG_PTOKEN_OUT: 508 if (Is_uhd_out_ready(ul_pipe)) 509 { 510 // OUT packet sent 511 uhd_ack_out_ready(ul_pipe); 512 uhd_freeze_pipe(ul_pipe); 513 return 1; 514 } 515 break; 516 } 517 518 return 0; 519 } 520 521 #endif // HOST_DEFINED
Note:
See TracChangeset
for help on using the changeset viewer.