⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cy7c67200_300_pcd.c

📁 cypress usb芯片驱动程序,该程序实现了cypress63700的3个驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
    lcd_read_reg (HOST1_IRQ_EN_REG, &intStat, cy_priv);    intStat &= ~VBUS_IRQ_EN;    lcd_write_reg(HOST1_IRQ_EN_REG, intStat, cy_priv);    /* Acknowledge interrupt */    lcd_write_reg(HOST1_STAT_REG, VBUS_IRQ_FLG, cy_priv);     if( cy_priv->lcd_priv == NULL || cy_priv->otg == NULL )    {        return;    }    vbus_timer.function = vbus_timeout;    vbus_timer.data = (unsigned long)cy_priv;    mod_timer( &vbus_timer, jiffies + 3 ); // 50 ms}/*****************************************************************/void pcd_irq_id(cy_priv_t *cy_priv){    unsigned short otg_stat_reg;    otg_t *otg = cy_priv->otg;    int prev_otg_id;    pcd_dbg("pcd_irq_id enter");            /* Acknowledge interrupt */    // Need to do this first since there is no conditioning on the     //     interrupt.    lcd_write_reg(HOST1_STAT_REG, ID_IRQ_FLG, cy_priv);    // not initialized    if( cy_priv->lcd_priv == NULL || otg == NULL )    {        return;    }    /* OTG ID has changed - we think */    /* Read the OTG ID Status bit USB Status Register for OTG ID pin */    lcd_read_reg(OTG_CTL_REG, &otg_stat_reg, cy_priv);    prev_otg_id = otg->id;    if (otg_stat_reg & OTG_ID_STAT)    {        otg->id = B_DEV;    }    else    {        otg->id = A_DEV;    }    if( prev_otg_id != otg->id )    {        update_otg_state(otg);       }}/*****************************************************************/void pcd_irq_mb_in(cy_priv_t *cy_priv){    // not used}/*****************************************************************/void pcd_irq_mb_out(unsigned int message, int sie, cy_priv_t * cy_priv){    unsigned i;             /* loop index */    unsigned short ep_number;    struct usb_endpoint_instance * endpoint;    sie_info *sie_var = (sie_info *)cy_priv->pcdi;    otg_t * otg = cy_priv->otg;        // not initialized yet, or wrong sie, ignore interrupt    if( sie_var == NULL || sie_var->sie_number != sie || sie_var->bus == NULL )    {        return;    }    for( i=1,ep_number=0; i!=0; ep_number++, i<<=1 )    {        //pcd_dbg("i:0x%04x, ep_num:%d", i, ep_number);        switch( message & i )        {        case SUSB_EP0_MSG: /* ignore ep0 */        default:            break;        case SUSB_EP1_MSG: /* endpoint done */        case SUSB_EP2_MSG:        case SUSB_EP3_MSG:        case SUSB_EP4_MSG:        case SUSB_EP5_MSG:        case SUSB_EP6_MSG:        case SUSB_EP7_MSG:            //pcd_dbg("EP_DONE_MSG_ID RECEIVED. Endpoint: %d", ep_number);            endpoint = &sie_var->bus->endpoint_array[ep_number];            if (endpoint->endpoint_address & USB_DIR_IN)             {                usbd_tx_complete_irq(endpoint, 0);                            if( endpoint->tx_urb )                {                    udc_start_in_irq(endpoint, endpoint->tx_urb->device);                }            }            else             {                ep_receive_data(endpoint, sie, cy_priv);            }            break;        case SUSB_RST_MSG: /* reset */            pcd_dbg("SUSB_RST_MSG");            usbd_device_event(sie_var->bus->device, DEVICE_RESET, 0);            if( otg != NULL )            {                otg->b_hnp_en = FALSE;                otg->a_bus_suspend = FALSE;                otg->b_bus_suspend = FALSE;                update_otg_state(otg);            }            break;        case SUSB_SOF_MSG:  /* active */            pcd_dbg("SUSB_SOF_MSG");            usbd_device_event(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0);            if( otg != NULL )            {                otg->a_bus_suspend = FALSE;                otg->b_bus_suspend = FALSE;                update_otg_state(otg);            }            break;        case SUSB_CFG_MSG: /* configured */            pcd_dbg("SUSB_CFG_MSG");            usbd_device_event(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0);            usbd_device_event(sie_var->bus->device, DEVICE_CONFIGURED, 0);            if( otg != NULL )            {                otg->a_bus_suspend = FALSE;                otg->b_bus_suspend = FALSE;                update_otg_state(otg);            }            break;        case SUSB_SUS_MSG: /* suspend */            pcd_dbg("SUSB_SUS_MSG");            usbd_device_event(sie_var->bus->device, DEVICE_BUS_INACTIVE, 0);            if( otg != NULL )            {                otg->a_bus_suspend = TRUE;                otg->b_bus_suspend = TRUE;                otg->b_bus_req = TRUE;                update_otg_state(otg);            }            break;        case 0x4000: /* b_hnp_enable */            if( otg != NULL )            {                pcd_dbg("b_hnp_enable");                otg->b_hnp_en = TRUE;                update_otg_state(otg);            }            break;        }    }}/***************************************************************** * * Function Name: ep_receive_data * * Description: This function sets up an endpoint to receive data *              on the EZ-HOST. * *****************************************************************/void ep_receive_data(struct usb_endpoint_instance *endpoint,                       int sie_num, cy_priv_t * cy_priv){    unsigned short length;    TRANSFER_FRAME frame;    int port_num;    //pcd_dbg("ep_receive_data enter: sie_num = %d", sie_num);    if( sie->sie_number != sie_num )    {        cy_err("message received on wrong sie: exptected=%d, actual= %d",                 sie->sie_number, sie_num);        return;    }    port_num = (sie_num == SIE1) ? PORT0 : PORT2;    if(endpoint->rcv_urb == NULL)     {        endpoint->rcv_urb = first_urb_detached(&endpoint->rdy);    }    /* check to see that we have an URB to receive data */    if(endpoint->rcv_urb)     {        int ep = endpoint->endpoint_address & 0xf;        unsigned short struct_location =             sie->recv_struct_location + ep*TXRX_STRUCT_SIZE;        unsigned short buff_location =            sie->recv_buffer_location + ep*RECV_BUFF_LENGTH;        /* read the buffer remainder and compute the number of bytes sent */        lcd_read_memory( struct_location + 4,                         2,                         (char *)&length,                         cy_priv);                length = sie->recv_buffer_length - length;        lcd_read_memory(buff_location,                         length,                         endpoint->rcv_urb->buffer,                         cy_priv);        /* submit the urb to the function driver */        usbd_rcv_complete_irq(endpoint, length, 0);                /* set the endpoint up to receive again with a pending receive SW           interrupt */        frame.link_pointer = 0x0000;        frame.absolute_address = buff_location;        frame.data_length = sie->recv_buffer_length;         frame.callback_function_location =  0;                   lcd_recv_data(struct_location,                       port_num,                       ep,                      8,                       (char*)&frame,                       NULL,                       0,                       cy_priv);                    }                  else    {        sie->rcv_data_pend_ep[endpoint->endpoint_address & 0xf] = endpoint;    }}/***************************************************************** * * Function Name: udc_rcv_urb_recycled * * Description: Notification from the core layer that an urb has been  *              recycled by the function driver. * *****************************************************************/void udc_rcv_urb_recycled(void){    size_t i;    struct usb_endpoint_instance *endpoint;    for(i=0; i<UDC_MAX_ENDPOINTS; i++)    {        endpoint = sie->rcv_data_pend_ep[i];        if( endpoint != 0 )        {            sie->rcv_data_pend_ep[i] = 0;            ep_receive_data(endpoint, sie->sie_number, sie->cy_priv);        }    }}/***************************************************************** * * Function Name: udc_start_in_irq * * Description:  Called by bi_send_urb, this function is registered with  * the peripheral core layer to transmit URB's onto the bus.  Called with  * interrupts disabled. * * We are requiring the URB buffer to be <= the send_data_buffer on the EZ-HOST * chip, so we check that it meets this requirement, and then move on.  We  * write the data to the buffer in EZ-HOST, and then trigger the SUSBx_SEND_INT * SW interrupt.  EZ-HOST then will take care of sending the data in packets  * over the bus.  When it is completed, it calls our callback function to  * notify us of success of failure.  It is possible to handle urb buffers  * larger than the EZ-HOST RAM send buffer space, by setting a flag here and  * then waiting for the callback to clear the flag, letting us know we can send * more data down to EZ-HOST.  For now anyway, we will keep it simple. If the  * data length of the URB is larger than the RAM buffer, we signal an error to  * the function driver.  * *****************************************************************/void udc_start_in_irq(struct usb_endpoint_instance * endpoint,                      struct usb_device_instance * device){    int sie;    int port_num;    int ep_addr;    struct usbd_urb * urb;    sie_info * sie_data;        //pcd_dbg("udc_start_in_irq enter");    /* determine the SIE this endpoint is associated with */    sie_data = (sie_info *)device->bus->privdata;    sie = sie_data->sie_number;        if (sie == SIE1)         port_num = PORT0;    else        port_num = PORT2;    ep_addr = endpoint->endpoint_address & 0x000f;        urb = endpoint->tx_urb;    /* check that we have an active URB to transmit */    if (urb)     {        if ((urb->actual_length - endpoint->sent) > 0)         {            endpoint->last = MIN(urb->actual_length - endpoint->sent,                                  sie_data->send_buffer_length);        }        else         {            endpoint->last = 0; // zero length packet        }        /* write the data to the RAM buffer */        if (lcd_write_memory(sie_data->send_buffer_location,                              endpoint->last,                              urb->buffer + endpoint->sent,                              sie_data->cy_priv) == SUCCESS)         {            TRANSFER_FRAME frame;            frame.link_pointer = 0x0000;            frame.absolute_address = sie_data->send_buffer_location;            frame.data_length = endpoint->last;            frame.callback_function_location = 0;            lcd_send_data(sie_data->send_struct_location,                           port_num,                           ep_addr,                           8,                           (char *)&frame,                           NULL,                           0,                           sie_data->cy_priv);        }                    }    else    {        pcd_dbg("No urb for transmit");    }}/***************************************************************** * * Function Name: udc_stall_ep * * * Description: This function will trigger the SUSBx_STALL_INT software  * interrupt on EZ-HOST.  This software interrupt is specific to the control * endpoint, so the only valid endpoint number is zero.  Triggering this  * interrupt will cause EZ-HOST to stall the next transaction on the default * endpoint. * *****************************************************************/void udc_stall_ep(unsigned int ep, struct usb_device_instance * device){    sie_info * sie_data = (sie_info *) device->bus->privdata;    lcd_int_data_t int_data;        pcd_dbg("udc_stall_ep enter: ep=%d", ep);    int_data.int_num = sie_data->susb_stall_interrupt;        /* ensure that the stall is for endpoint zero, otherwise do nothing */    if (ep == 0)     {        lcd_exec_interrupt(&int_data, NULL, 0, sie_data->cy_priv);    }}/***************************************************************** * * Function Name: udc_reset_ep * * Description: The BIOS does not provide a way to directly reset a specific * endpoint, so nothing will be done inside of this function.  The purpose of * the function is for bus interfaces that allow direct manipulation of each * endpoint, this gives the peripheral core a chance to reset each endpoint * during initialization.  However, with the EZ-HOST BIOS, this is performed * by calling the SUSB_INIT_INT software interrupt, to reset all endpoints  * based on the configuration loaded to EZ-HOST. * *****************************************************************/void udc_reset_ep(unsigned int ep, struct usb_device_instance * device){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -