Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id: usb-drv-as3525.c 25996 2010-05-13 14:07:59Z ranma $
- *
- * Copyright © 2009 Rafaël Carré
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
- #include "system.h"
- #include "usb.h"
- #include "usb_drv.h"
- #include "as3525.h"
- #include "clock-target.h"
- #include "ascodec.h"
- #include "as3514.h"
- #include <stdbool.h>
- #include "panic.h"
- /*#define LOGF_ENABLE*/
- #define LOGF_ENABLE
- #include "logf.h"
- #include "usb_ch9.h"
- #include "usb_core.h"
- #include "string.h"
- /* 4 input endpoints */
- #define USB_IEP_CTRL(i) *((volatile unsigned long*) (USB_BASE + 0x0000 + (i*0x20)))
- #define USB_IEP_STS(i) *((volatile unsigned long*) (USB_BASE + 0x0004 + (i*0x20)))
- #define USB_IEP_TXFSIZE(i) *((volatile unsigned long*) (USB_BASE + 0x0008 + (i*0x20)))
- #define USB_IEP_MPS(i) *((volatile unsigned long*) (USB_BASE + 0x000C + (i*0x20)))
- #define USB_IEP_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0014 + (i*0x20)))
- #define USB_IEP_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x0018 + (i*0x20)))
- /* 4 output endpoints */
- #define USB_OEP_CTRL(i) *((volatile unsigned long*) (USB_BASE + 0x0200 + (i*0x20)))
- #define USB_OEP_STS(i) *((volatile unsigned long*) (USB_BASE + 0x0204 + (i*0x20)))
- #define USB_OEP_RXFR(i) *((volatile unsigned long*) (USB_BASE + 0x0208 + (i*0x20)))
- #define USB_OEP_MPS(i) *((volatile unsigned long*) (USB_BASE + 0x020C + (i*0x20)))
- #define USB_OEP_SUP_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0210 + (i*0x20)))
- #define USB_OEP_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x0214 + (i*0x20)))
- #define USB_OEP_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x0218 + (i*0x20)))
- #define USB_DEV_CFG *((volatile unsigned long*) (USB_BASE + 0x0400))
- #define USB_DEV_CTRL *((volatile unsigned long*) (USB_BASE + 0x0404))
- #define USB_DEV_STS *((volatile unsigned long*) (USB_BASE + 0x0408))
- #define USB_DEV_INTR *((volatile unsigned long*) (USB_BASE + 0x040C))
- #define USB_DEV_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x0410))
- #define USB_DEV_EP_INTR *((volatile unsigned long*) (USB_BASE + 0x0414))
- #define USB_DEV_EP_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x0418))
- #define USB_PHY_EP0_INFO *((volatile unsigned long*) (USB_BASE + 0x0504))
- #define USB_PHY_EP1_INFO *((volatile unsigned long*) (USB_BASE + 0x0508))
- #define USB_PHY_EP2_INFO *((volatile unsigned long*) (USB_BASE + 0x050C))
- #define USB_PHY_EP3_INFO *((volatile unsigned long*) (USB_BASE + 0x0510))
- #define USB_PHY_EP4_INFO *((volatile unsigned long*) (USB_BASE + 0x0514))
- #define USB_PHY_EP5_INFO *((volatile unsigned long*) (USB_BASE + 0x0518))
- /* 4 channels */
- #define USB_HOST_CH_SPLT(i) *((volatile unsigned long*) (USB_BASE + 0x1000 + (i*0x20)))
- #define USB_HOST_CH_STS(i) *((volatile unsigned long*) (USB_BASE + 0x1004 + (i*0x20)))
- #define USB_HOST_CH_TXFSIZE(i) *((volatile unsigned long*) (USB_BASE + 0x1008 + (i*0x20)))
- #define USB_HOST_CH_REQ(i) *((volatile unsigned long*) (USB_BASE + 0x100C + (i*0x20)))
- #define USB_HOST_CH_PER_INFO(i) *((volatile unsigned long*) (USB_BASE + 0x1010 + (i*0x20)))
- #define USB_HOST_CH_DESC_PTR(i) *((volatile unsigned long*) (USB_BASE + 0x1014 + (i*0x20)))
- #define USB_HOST_CH_STS_MASK(i) *((volatile unsigned long*) (USB_BASE + 0x1018 + (i*0x20)))
- #define USB_HOST_CFG *((volatile unsigned long*) (USB_BASE + 0x1400))
- #define USB_HOST_CTRL *((volatile unsigned long*) (USB_BASE + 0x1404))
- #define USB_HOST_INTR *((volatile unsigned long*) (USB_BASE + 0x140C))
- #define USB_HOST_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x1410))
- #define USB_HOST_CH_INTR *((volatile unsigned long*) (USB_BASE + 0x1414))
- #define USB_HOST_CH_INTR_MASK *((volatile unsigned long*) (USB_BASE + 0x1418))
- #define USB_HOST_FRAME_INT *((volatile unsigned long*) (USB_BASE + 0x141C))
- #define USB_HOST_FRAME_REM *((volatile unsigned long*) (USB_BASE + 0x1420))
- #define USB_HOST_FRAME_NUM *((volatile unsigned long*) (USB_BASE + 0x1424))
- #define USB_HOST_PORT0_CTRL_STS *((volatile unsigned long*) (USB_BASE + 0x1500))
- #define USB_OTG_CSR *((volatile unsigned long*) (USB_BASE + 0x2000))
- #define USB_I2C_CSR *((volatile unsigned long*) (USB_BASE + 0x2004))
- #define USB_GPIO_CSR *((volatile unsigned long*) (USB_BASE + 0x2008))
- #define USB_SNPSID_CSR *((volatile unsigned long*) (USB_BASE + 0x200C))
- #define USB_USERID_CSR *((volatile unsigned long*) (USB_BASE + 0x2010))
- #define USB_USER_CONF1 *((volatile unsigned long*) (USB_BASE + 0x2014))
- #define USB_USER_CONF2 *((volatile unsigned long*) (USB_BASE + 0x2018))
- #define USB_USER_CONF3 *((volatile unsigned long*) (USB_BASE + 0x201C))
- #define USB_USER_CONF4 *((volatile unsigned long*) (USB_BASE + 0x2020))
- #define USB_USER_CONF5 *((volatile unsigned long*) (USB_BASE + 0x2024))
- /* write bits 31..16 */
- #define USB_GPIO_IDDIG_SEL (1<<30)
- #define USB_GPIO_FS_DATA_EXT (1<<29)
- #define USB_GPIO_FS_SE0_EXT (1<<28)
- #define USB_GPIO_FS_XCVR_OWNER (1<<27)
- #define USB_GPIO_TX_ENABLE_N (1<<26)
- #define USB_GPIO_TX_BIT_STUFF_EN (1<<25)
- #define USB_GPIO_BSESSVLD_EXT (1<<24)
- #define USB_GPIO_ASESSVLD_EXT (1<<23)
- #define USB_GPIO_VBUS_VLD_EXT (1<<22)
- #define USB_GPIO_VBUS_VLD_EXT_SEL (1<<21)
- #define USB_GPIO_XO_ON (1<<20)
- #define USB_GPIO_CLK_SEL11 (3<<18)
- #define USB_GPIO_CLK_SEL10 (2<<18)
- #define USB_GPIO_CLK_SEL01 (1<<18)
- #define USB_GPIO_CLK_SEL00 (0<<18)
- #define USB_GPIO_XO_EXT_CLK_ENBN (1<<17)
- #define USB_GPIO_XO_REFCLK_ENB (1<<16)
- /* readronly bits 15..0 */
- #define USB_GPIO_PHY_VBUSDRV (1<< 1)
- #define USB_GPIO_HS_INTR (1<< 0)
- /* Device Control Register and bit fields */
- #define USB_DEV_CTRL_REMOTE_WAKEUP 0x00000001 // set remote wake-up signal
- #define USB_DEV_CTRL_RDE 0x00000004 // receive dma enable
- #define USB_DEV_CTRL_DESC_UPDATE 0x00000010 // descriptor update
- #define USB_DEV_CTRL_THRES_ENABLE 0x00000080 // threshold enable
- #define USB_DEV_CTRL_BURST_CONTROL 0x00000100 // burst control
- #define USB_DEV_CTRL_SOFT_DISCONN 0x00000400 // soft disconnect
- #define USB_DEV_CTRL_APCSR_DONE 0x00002000 // app Prog CSR Done
- #define USB_DEV_CTRL_MASK_BURST_LEN 0x000f0000 // mask for burst length
- #define USB_DEV_CTRL_MASK_THRESHOLD_LEN 0xff000000 // mask for threshold length
- /* settings of burst length for maskBurstLen_c field */
- #define USB_DEV_CTRL_BLEN_1DWORD 0x00000000
- #define USB_DEV_CTRL_BLEN_2DWORDS 0x00010000
- #define USB_DEV_CTRL_BLEN_4DWORDS 0x00020000
- #define USB_DEV_CTRL_BLEN_8DWORDS 0x00030000
- #define USB_DEV_CTRL_BLEN_16DWORDS 0x00040000
- #define USB_DEV_CTRL_BLEN_32DWORDS 0x00050000
- #define USB_DEV_CTRL_BLEN_64DWORDS 0x00060000
- #define USB_DEV_CTRL_BLEN_128DWORDS 0x00070000
- #define USB_DEV_CTRL_BLEN_256DWORDS 0x00080000
- #define USB_DEV_CTRL_BLEN_512DWORDS 0x00090000
- /* settings of threshold length for maskThresholdLen_c field */
- #define USB_DEV_CTRL_TLEN_1DWORD 0x00000000
- #define USB_DEV_CTRL_TLEN_HALFMAXSIZE 0x01000000
- #define USB_DEV_CTRL_TLEN_4THMAXSIZE 0x02000000
- #define USB_DEV_CTRL_TLEN_8THMAXSIZE 0x03000000
- #define USB_DEV_CFG_HS 0x00000000
- #define USB_DEV_CFG_FS 0x00000001 /* 30 or 60MHz */
- #define USB_DEV_CFG_LS 0x00000002
- #define USB_DEV_CFG_FS_48 0x00000003 /* 48MHz */
- #define USB_DEV_CFG_REMOTE_WAKEUP 0x00000004
- #define USB_DEV_CFG_SELF_POWERED 0x00000008
- #define USB_DEV_CFG_SYNC_FRAME 0x00000010
- #define USB_DEV_CFG_PI_16BIT 0x00000000
- #define USB_DEV_CFG_PI_8BIT 0x00000020
- #define USB_DEV_CFG_UNI_DIR 0x00000000
- #define USB_DEV_CFG_BI_DIR 0x00000040
- #define USB_DEV_CFG_STAT_ACK 0x00000000
- #define USB_DEV_CFG_STAT_STALL 0x00000080
- /* EP Control Register Fields */
- #define USB_EP_CTRL_STALL 0x00000001
- #define USB_EP_CTRL_FLUSH 0x00000002 /* EP In data fifo Flush */
- #define USB_EP_CTRL_SNOOP_MODE 0x00000004 // snoop mode for out endpoint
- #define USB_EP_CTRL_PD 0x00000008 /* EP Poll Demand */
- #define USB_EP_CTRL_EPTYPE_MASK 0x00000030 // bit 5-4: endpoint types
- #define USB_EP_TYPE_CONTROL 0x00000000 // control endpoint
- #define USB_EP_TYPE_ISO 0x00000010 // isochronous endpoint
- #define USB_EP_TYPE_BULK 0x00000020 // bulk endpoint
- #define USB_EP_TYPE_INTERRUPT 0x00000030 // interrupt endpoint
- #define USB_EP_CTRL_NAK 0x00000040 /* EP NAK Status */
- #define USB_EP_CTRL_SNAK 0x00000080 /* EP Set NAK Bit */
- #define USB_EP_CTRL_CNAK 0x00000100 /* EP Clr NAK Bit */
- #define USB_EP_CTRL_ACT 0x00000400 /* EP Clr NAK Bit */
- /*-------------------------*/
- /* DMA Related Definitions */
- /*-------------------------*/
- /* Description of the status quadlets */
- #define USB_DMA_DESC_BUFF_STS 0x80000000 /* Buffer Status */
- #define USB_DMA_DESC_BS_HST_RDY 0x80000000 /* Host Ready */
- #define USB_DMA_DESC_BS_DMA_DONE 0x00000000 /* DMA Done */
- #define USB_DMA_DESC_ZERO_LEN 0x40000000 /* zero length packet */
- #define USB_DMA_DESC_EARY_INTR 0x20000000 /* early interrupt */
- #define USB_DMA_DESC_RXTX_STS 0x10000000
- #define USB_DMA_DESC_RTS_SUCC 0x00000000 /* Success */
- #define USB_DMA_DESC_RTS_BUFERR 0x10000000 /* Buffer Error */
- #define USB_DMA_DESC_LAST 0x08000000
- #define USB_DMA_DESC_MASK_FRAM_NUM 0x07ff0000 // bits 26-16: frame number for iso
- #define USB_DMA_DESC_RXTX_BYTES 0x0000FFFF
- /* setup descriptor */
- #define SETUP_MASK_CONFIG_STAT 0x0fff0000
- #define SETUP_MASK_CONFIG_NUM 0x0f000000
- #define SETUP_MASK_IF_NUM 0x00f00000
- #define SETUP_MASK_ALT_SETNUM 0x000f0000
- struct usb_endpoint
- {
- void *buf;
- unsigned int len;
- union
- {
- unsigned int sent;
- unsigned int received;
- };
- bool wait;
- bool busy;
- };
- static struct usb_endpoint endpoints[USB_NUM_ENDPOINTS*2];
- struct usb_dev_dma_desc {
- volatile int status;
- volatile int resv;
- volatile void *data_ptr;
- volatile void *next_desc;
- };
- struct usb_dev_setup_buf {
- volatile int status;
- volatile int resv;
- volatile int data1; /* first 4 bytes of data */
- volatile int data2; /* last 4 bytes of data */
- };
- static struct usb_dev_dma_desc desc[2];
- static struct usb_dev_dma_desc *uc_desc[2];
- static struct usb_dev_setup_buf setup_desc;
- static char rx_buf[512];
- static char tx_buf[512];
- void usb_attach(void)
- {
- usb_enable(true);
- }
- static inline void usb_delay(int delay)
- { //TUNEME : delay is in milliseconds
- delay <<= 14;
- while(delay--) ;
- }
- static void usb_phy_on(void)
- {
- /* PHY clock */
- CGU_USB = 1<<5 /* enable */
- | (CLK_DIV(AS3525_PLLB_FREQ, 48000000) / 2) << 2
- | 2; /* source = PLLB */
- /* UVDD on */
- ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) | (1<<4));
- usb_delay(100);
- /* reset */
- CCU_SRC = CCU_SRC_USB_AHB_EN|CCU_SRC_USB_PHY_EN;
- CCU_SRL = CCU_SRL_MAGIC_NUMBER;
- usb_delay(1);
- CCU_SRC = CCU_SRC_USB_AHB_EN;
- usb_delay(1);
- CCU_SRC = CCU_SRL = 0;
- USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
- | USB_GPIO_TX_BIT_STUFF_EN
- | USB_GPIO_XO_ON
- | USB_GPIO_CLK_SEL10; /* 0x06180000; */
- }
- static void usb_phy_suspend(void)
- {
- USB_GPIO_CSR |= USB_GPIO_ASESSVLD_EXT |
- USB_GPIO_BSESSVLD_EXT |
- USB_GPIO_VBUS_VLD_EXT;
- usb_delay(3);
- USB_GPIO_CSR |= USB_GPIO_VBUS_VLD_EXT_SEL;
- usb_delay(10);
- }
- static void usb_phy_resume(void)
- {
- USB_GPIO_CSR &= ~(USB_GPIO_ASESSVLD_EXT |
- USB_GPIO_BSESSVLD_EXT |
- USB_GPIO_VBUS_VLD_EXT);
- usb_delay(3);
- USB_GPIO_CSR &= ~USB_GPIO_VBUS_VLD_EXT_SEL;
- usb_delay(10);
- }
- #if 0
- static void extmem_read_loop(void)
- {
- int *extmem_start = (int*)0x30000000;
- int *extmem_end = (int*)0x301fffff;
- int *ptr = extmem_start;
- disable_irq_save();
- GPIOA_PIN(5) = 0;
- GPIOA_PIN(7) = 0;
- while (1) {
- asm volatile ("ldr r0, [%0] \n"
- "ldr r0, [%0, #4] \n"
- "ldr r0, [%0, #8] \n"
- "ldr r0, [%0, #12]" :: "r"(ptr));
- ptr+=4;
- if (ptr >= extmem_end)
- ptr = extmem_start;
- }
- }
- static void intmem_read_loop(void)
- {
- int *intmem_start = (int*)0x00000000;
- int *intmem_end = (int*)0x0005ffff;
- int *ptr = intmem_start;
- disable_irq_save();
- GPIOA_PIN(5) = 0;
- GPIOA_PIN(7) = 0;
- while (1) {
- asm volatile ("ldr r0, [%0] \n"
- "ldr r0, [%0, #4] \n"
- "ldr r0, [%0, #8] \n"
- "ldr r0, [%0, #12]" :: "r"(ptr));
- ptr+=4;
- if (ptr >= intmem_end)
- ptr = intmem_start;
- }
- }
- #endif
- static void setup_desc_init(struct usb_dev_setup_buf *desc)
- {
- struct usb_dev_setup_buf *uc_desc = UNCACHED_ADDR(desc);
- uc_desc->status = USB_DMA_DESC_BS_HST_RDY;
- uc_desc->resv = 0xffffffff;
- uc_desc->data1 = 0xffffffff;
- uc_desc->data2 = 0xffffffff;
- }
- static void dma_desc_init(void)
- {
- uc_desc[0] = UNCACHED_ADDR(&desc[0]);
- uc_desc[1] = UNCACHED_ADDR(&desc[1]);
- uc_desc[0]->status = USB_DMA_DESC_BS_DMA_DONE | USB_DMA_DESC_LAST | 0x40;
- uc_desc[0]->resv = 0xffffffff;
- uc_desc[0]->data_ptr = tx_buf;
- uc_desc[0]->next_desc = &desc[0];
- USB_IEP_DESC_PTR(0) = (int)&desc[0];
- uc_desc[1]->status = USB_DMA_DESC_BS_HST_RDY | USB_DMA_DESC_LAST | 0x40;
- uc_desc[1]->resv = 0xffffffff;
- uc_desc[1]->data_ptr = rx_buf;
- uc_desc[1]->next_desc = &desc[1];
- USB_OEP_DESC_PTR(0) = (int)&desc[1];
- setup_desc_init(&setup_desc);
- USB_OEP_SUP_PTR(0) = (int)&setup_desc;
- }
- void usb_drv_init(void)
- {
- int i;
- for(i = 0; i < USB_NUM_ENDPOINTS * 2; i++)
- endpoints[i].busy = false;
- logf("usb_drv_init() !!!!\n");
- /* length regulator: normal operation */
- ascodec_write(AS3514_CVDD_DCDC3, ascodec_read(AS3514_CVDD_DCDC3) | 1<<2);
- /* AHB part */
- CGU_PERI |= CGU_USB_CLOCK_ENABLE;
- /* reset AHB */
- CCU_SRC = CCU_SRC_USB_AHB_EN;
- CCU_SRL = CCU_SRL_MAGIC_NUMBER;
- usb_delay(1);
- CCU_SRC = CCU_SRL = 0;
- USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
- | USB_GPIO_TX_BIT_STUFF_EN
- | USB_GPIO_XO_ON
- | USB_GPIO_CLK_SEL10; /* 0x06180000; */
- /* bug workaround according to linux patch */
- USB_DEV_CFG = (USB_DEV_CFG & ~3) | 1; /* full speed */
- /* enable soft disconnect */
- USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;
- usb_phy_on();
- usb_phy_suspend();
- USB_DEV_CTRL |= USB_DEV_CTRL_SOFT_DISCONN;
- USB_IEP_CTRL(0) &= (3 << 4); /* control endpoint */
- USB_IEP_DESC_PTR(0) = 0;
- USB_OEP_CTRL(0) &= (3 << 4); /* control endpoint */
- USB_OEP_DESC_PTR(0) = 0;
- USB_DEV_INTR_MASK &= ~0x7f; /* unmask all flags */
- USB_DEV_INTR_MASK |= 0x20; /* mask SOF */
- USB_DEV_CFG = USB_DEV_CFG_STAT_ACK |
- USB_DEV_CFG_UNI_DIR |
- USB_DEV_CFG_PI_16BIT |
- USB_DEV_CFG_HS |
- USB_DEV_CFG_SELF_POWERED |
- 0x20200;
- USB_DEV_CTRL = USB_DEV_CTRL_BLEN_1DWORD |
- USB_DEV_CTRL_DESC_UPDATE |
- USB_DEV_CTRL_THRES_ENABLE |
- USB_DEV_CTRL_RDE |
- 0x04000000;
- USB_DEV_EP_INTR_MASK &= ~((1<<0) | (1<<16)); /* ep 0 */
- USB_DEV_EP_INTR_MASK = 0; /* FIXME: test */
- dma_desc_init();
- USB_IEP_MPS(0) = 0x40;
- USB_IEP_STS_MASK(0) = 0x0040; /* OF: 0x840 */
- USB_IEP_TXFSIZE(0) = 0x20;
- USB_OEP_MPS(0) = 0x08000040;
- USB_OEP_STS_MASK(0) = 0x0000; /* OF: 0x1800 */
- USB_OEP_RXFR(0) = 0x00;
- USB_IEP_CTRL(0) |= USB_EP_CTRL_FLUSH|USB_EP_CTRL_SNAK; /* set NAK */
- USB_OEP_CTRL(0) |= USB_EP_CTRL_FLUSH|USB_EP_CTRL_SNAK; /* set NAK */
- /* clear pending interrupts */
- USB_DEV_EP_INTR = 0xffffffff;
- USB_DEV_INTR = 0xffffffff;
- VIC_INT_ENABLE = INTERRUPT_USB;
- usb_phy_resume();
- USB_DEV_CTRL &= ~USB_DEV_CTRL_SOFT_DISCONN;
- USB_GPIO_CSR = USB_GPIO_TX_ENABLE_N
- | USB_GPIO_TX_BIT_STUFF_EN
- | USB_GPIO_XO_ON
- | USB_GPIO_HS_INTR
- | USB_GPIO_CLK_SEL10; /* 0x06180000; */
- }
- void usb_drv_exit(void)
- {
- USB_DEV_CTRL |= (1<<10); /* soft disconnect */
- VIC_INT_EN_CLEAR = INTERRUPT_USB;
- #if 0
- CGU_USB &= ~(1<<5);
- CGU_PERI &= ~CGU_USB_CLOCK_ENABLE;
- /* Disable UVDD generating LDO */
- ascodec_write(AS3517_USB_UTIL, ascodec_read(AS3517_USB_UTIL) & ~(1<<4));
- #endif
- logf("usb_drv_exit() !!!!\n");
- }
- int usb_drv_port_speed(void)
- {
- return (USB_DEV_CFG & 3) ? 0 : 1;
- }
- int usb_drv_request_endpoint(int type, int dir)
- {
- /* type 2, dir 128: bulk, in (to host) */
- /* logf("%s(type=%d,dir=%d)\n",__func__,type,dir); */
- (void) type;
- int i = dir == USB_DIR_IN ? 2 : 3; /* skip the control ep */
- for(; i < USB_NUM_ENDPOINTS * 2; i += 2)
- if(!endpoints[i].busy)
- {
- endpoints[i].busy = true;
- i >>= 1;
- if (dir == USB_DIR_IN) {
- USB_DEV_EP_INTR_MASK &= ~(1<<i);
- USB_IEP_CTRL(i) = USB_EP_CTRL_FLUSH|USB_EP_CTRL_CNAK|USB_EP_CTRL_ACT|(type << 4);
- } else {
- USB_DEV_EP_INTR_MASK &= ~(1<<(16+i));
- USB_OEP_CTRL(i) = USB_EP_CTRL_FLUSH|USB_EP_CTRL_CNAK|USB_EP_CTRL_ACT|(type << 4);
- }
- return i | dir;
- }
- return -1;
- }
- void usb_drv_release_endpoint(int ep)
- {
- int i = (ep & 0x7f) * 2;
- /* logf("%s(ep=%d,dir=%d)\n",__func__,ep&0x7f,ep&0x80); */
- if (ep == 0) /* Don't mask control EP? */
- return;
- if(!(ep & USB_DIR_IN))
- i++;
- endpoints[i].busy = false;
- if (ep & USB_DIR_IN) {
- USB_DEV_EP_INTR_MASK |= (1<<ep);
- } else {
- USB_DEV_EP_INTR_MASK |= (1<<(16+ep));
- }
- }
- void usb_drv_cancel_all_transfers(void)
- {
- }
- int usb_drv_recv(int ep, void *ptr, int len)
- {
- logf("usb_drv_recv(%d,%x,%d)\n", ep, (int)ptr, len);
- if (len == 0) {
- if (ep != 0)
- panicf("%s(%d,%d) zero length?", __func__, ep, len);
- return 0;
- }
- if ((ep & 1) != 1)
- panicf("%s(%d,%x,%d) not out ep?", __func__, ep,(int)ptr,len);
- panicf("%s(%d,%x,%d)", __func__,ep,(int)ptr,len);
- (void)ep;(void)ptr;(void)len;
- if(ep >= 2)
- return -1;
- return -1;
- }
- volatile int tx_done;
- static char hexbuf[1025];
- static char hextab[16] = "0123456789abcdef";
- char *make_hex(char *data, int len)
- {
- int i;
- if (len > 512)
- len = 512;
- for (i=0; i<len; i++) {
- hexbuf[2*i ] = hextab[(unsigned char)data[i] >> 4 ];
- hexbuf[2*i+1] = hextab[(unsigned char)data[i] & 0xf];
- }
- hexbuf[2*i] = 0;
- return hexbuf;
- }
- int usb_drv_send(int ep, void *ptr, int len)
- {
- logf("usb_drv_send(%d,%x,%d)\n", ep, (int)ptr, len);
- tx_done = 0;
- if ((ep & 1) != 0)
- panicf("%s(%d,%x,%d) not in ep?", __func__, ep,(int)ptr,len);
- if (ep == 0) {
- void *uc_buf = UNCACHED_ADDR((void*)tx_buf);
- char *data = ptr;
- if (len>64)
- panicf("%s(%d,%x,%d) len>64!", __func__, ep,(int)ptr,len);
- logf("sending: %s\n", make_hex(data, len));
- memcpy(uc_buf, ptr, len);
- uc_desc[0]->status = USB_DMA_DESC_BS_HST_RDY |
- USB_DMA_DESC_LAST |
- len;
- /* uc_desc[0]->status = USB_DMA_DESC_BS_HST_RDY | USB_DMA_DESC_LAST | 64; */
- uc_desc[0]->resv = 0xffffffff;
- uc_desc[0]->next_desc = &desc[0];
- uc_desc[0]->data_ptr = tx_buf;
- /*USB_IEP_TXFSIZE(0) = len;*/
- USB_IEP_CTRL(0) |= USB_EP_CTRL_FLUSH;
- USB_IEP_DESC_PTR(0) = (int)&desc[0];
- USB_IEP_STS(0) = USB_IEP_STS(0); /* clear status */
- USB_IEP_CTRL(0) |= USB_EP_CTRL_CNAK|USB_EP_CTRL_PD; /* signal poll demand */
- while (!tx_done);
- return 0;
- }
- if(ep >= 2)
- panicf("%s(%d,%x,%d)", __func__,ep,(int)ptr,len);
- return -1;
- return -1;
- }
- int usb_drv_send_nonblocking(int ep, void *ptr, int len)
- {
- logf("usb_drv_send_nonblocking(%d,%x,%d)\n", ep, (int)ptr, len);
- /* TODO */
- return usb_drv_send(ep, ptr, len);
- }
- int irq_4 = 0;
- int irq_8 = 0;
- int irq_10 = 0;
- int irq_20 = 0;
- int irq_40 = 0;
- /* interrupt service routine */
- void INT_USB(void)
- {
- int ep = USB_DEV_EP_INTR & ~USB_DEV_EP_INTR_MASK; // = 0x10001 (in/out)
- int intr = USB_DEV_INTR & ~USB_DEV_INTR_MASK;
- struct usb_ctrlrequest *req = (void*)UNCACHED_ADDR(&setup_desc.data1);
- logf("INT_USB(ep=%x[r:%lx,m:%lx],intr=%x[r:%lx,m:%lx])\n",
- ep, USB_DEV_EP_INTR, USB_DEV_EP_INTR_MASK,
- intr, USB_DEV_INTR, USB_DEV_INTR_MASK);
- GPIOA_PIN(5) ^= 0xff;
- if(ep)
- {
- USB_DEV_EP_INTR = ep;
- if(ep & (1<<0)) // ctrl in
- {
- int ep_sts = USB_IEP_STS(0) & ~USB_IEP_STS_MASK(0);
- ep &= ~(1<<0);
- logf("ctrl in, status %lx\n", USB_IEP_STS(0));
- USB_IEP_STS(0) = ep_sts; /* ack */
- if (ep_sts & 0x40) {
- char *uc_buf = UNCACHED_ADDR((void*)tx_buf);
- ep_sts &= ~0x40;
- logf("IN, resending?\n");
- uc_buf[0] = 0x5a;
- uc_buf[1] = 0xa5;
- uc_desc[0]->status |= USB_DMA_DESC_BS_HST_RDY;
- /* uc_desc[0]->status = USB_DMA_DESC_BS_HST_RDY | USB_DMA_DESC_LAST | 64; */
- USB_IEP_CTRL(0) |= /*USB_EP_CTRL_SNAK|*/USB_EP_CTRL_PD;
- }
- if (ep_sts & 0x400) {
- ep_sts &= ~0x400;
- /*USB_IEP_CTRL(0) |= USB_EP_CTRL_SNAK|USB_EP_CTRL_FLUSH*/;
- USB_IEP_CTRL(0) |= USB_EP_CTRL_SNAK;
- logf("tx done\n");
- /* usb_core_transfer_complete(0, USB_DIR_IN, 0, 12); */
- tx_done = 1;
- }
- if (ep_sts) {
- panicf("ctrl in 0x%x %x",(int)USB_IEP_STS(0),ep);
- }
- }
- if(ep & (1<<1)) // bulk in
- {
- }
- if(ep & (1<<3)) // intr in
- {
- }
- if(ep & (1<<16)) // ctrl out
- {
- int ep_sts = USB_OEP_STS(0) & ~USB_OEP_STS_MASK(0);
- ep &= ~(1<<16);
- logf("ctrl out, status %lx\n", USB_OEP_STS(0));
- /*
- struct usb_dev_setup_buf *uc_desc = UNCACHED_ADDR(&setup_desc);
- panicf("ctrl out 0x%x %x %x %x %x",(int)USB_OEP_STS(0),ep,
- uc_desc->status,
- uc_desc->data1,
- uc_desc->data2);
- */
- USB_OEP_STS(0) = ep_sts; /* ACK */
- if (ep_sts & 0x10) {
- ep_sts &= ~0x10;
- logf("got out token, status=%08x\n", uc_desc[1]->status);
- uc_desc[1]->status = USB_DMA_DESC_BS_HST_RDY |
- USB_DMA_DESC_LAST | 0x40;
- }
- if (ep_sts & 0x20) {
- static struct usb_ctrlrequest req_copy;
- ep_sts &= ~0x20;
- req_copy = *req;
- logf("got setup packet: type=%d req=%d val=%d ind=%d len=%d\n",
- req->bRequestType,
- req->bRequest,
- req->wValue,
- req->wIndex,
- req->wLength);
- usb_core_control_request(&req_copy);
- setup_desc_init(&setup_desc);
- } else {
- panicf("in: %x %x %x", setup_desc.status,
- setup_desc.data1,
- setup_desc.data2);
- }
- }
- if(ep & (1<<17)) // bulk out
- {
- }
- if (ep)
- panicf("USB : 0x%x", ep);
- }
- if(intr)
- {
- USB_DEV_INTR = intr; /* ack interrupt */
- if (intr & 0x4) {/* idle >3ms detected */
- intr &= ~0x4;
- irq_4++;
- logf("usb idle\n");
- }
- if (intr & 0x8) {/* usb reset from host? */
- intr &= ~0x8;
- irq_8++;
- logf("usb reset\n");
- }
- if (intr & 0x10) {/* suspend req from host? */
- intr &= ~0x10;
- irq_10++;
- logf("usb suspend\n");
- }
- if (intr & 0x20) {/* sof received */
- intr &= ~0x20;
- irq_20++;
- logf("sof\n");
- }
- if (intr & 0x40) {/* speed enumeration complete */
- int spd = USB_DEV_STS & 0x00006000; /* Enumerated Speed */
- intr &= ~0x40;
- irq_40++;
- logf("speed enum complete: ");
- if (spd == 0x0000) logf("hs\n");
- if (spd == 0x2000) logf("fs\n");
- if (spd == 0x4000) logf("ls\n");
- USB_PHY_EP0_INFO = 0x00200000;
- USB_DEV_CTRL |= USB_DEV_CTRL_APCSR_DONE;
- USB_IEP_CTRL(0) |= USB_EP_CTRL_ACT;
- USB_OEP_CTRL(0) |= USB_EP_CTRL_ACT;
- USB_IEP_CTRL(0) |= USB_EP_CTRL_CNAK|USB_EP_CTRL_FLUSH; /* clear NAK */
- USB_OEP_CTRL(0) |= USB_EP_CTRL_CNAK|USB_EP_CTRL_FLUSH; /* clear NAK */
- }
- if (intr)
- panicf("usb devirq 0x%x", intr);
- }
- USB_DEV_CTRL |= USB_DEV_CTRL_RDE;
- }
- /* (not essential? , not implemented in usb-tcc.c) */
- void usb_drv_set_test_mode(int mode)
- {
- (void)mode;
- }
- void usb_drv_set_address(int address)
- {
- (void)address;
- }
- void usb_drv_stall(int ep, bool stall, bool in)
- {
- (void)ep;(void)stall;(void)in;
- }
- bool usb_drv_stalled(int ep, bool in)
- {
- (void)ep;(void)in;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement