Beispiel #1
0
static void usbc_core_handle_set_address()
{
    usbc_core_t* pUsbCore = usbc_core_get_instance();
    kal_uint16 wValue = pUsbCore->setup_packet.wValue;

    usbc_core_printf("=========>usbcore_handle_set_address\r\n");
    usbc_trace_info(USBCORE_SET_ADDRESS, (wValue & 0x7f));

    usbc_core_set_usb_address(wValue & 0x7f);
    usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
}
kal_bool usbc_class_device_submit_control_request(
    kal_uint8 class_device_id, kal_uint8* buffer, kal_uint32 length,
    usbc_control_request_type_e type)
{
    usbc_core_t* pUsbCore = usbc_core_get_instance();

    if (!USBC_IS_IN_EXCEPTION_MODE())
    {
        USBC_CLASS_DEVICE_CONTEXT_CHECK();
    }

    if ( (class_device_id >= pUsbCore->total_class_devices) ||
         (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) )
    {
        ASSERT(0);
        return KAL_FALSE;
    }

    usbc_core_set_control_request(buffer, length, type);

    return KAL_TRUE;
}
Beispiel #3
0
static void usbc_core_handle_get_status()
{
    usbc_core_t* pUsbCore = usbc_core_get_instance();
    usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
    kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
    //kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
    kal_uint8* pBuffer = pUsbCore->control_request_buffer;
    kal_uint32 length = 0;

    usbc_core_printf("=========>usbcore_handle_get_status\r\n");
    usbc_trace_info(USBCORE_GET_STATUS, bRecip);

    if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
    {
        kal_uint8 i;

        /* D0: Self Powered, D1: Remote Wakeup */
        pBuffer[0] = 0;     //Bus Power
        pBuffer[1] = 0;     //No Remote Wakeup
        length = 2;
        type = USBC_CONTROL_REQUEST_TYPE_SEND;

        // report remote wakeup status in USB 1.1 and USB 2.0 (0 in USB 3.0)
        if( pUsbCore->speed != USBC_USB_SPEED_USB30 )
        {
            for( i=0; i<pUsbCore->total_class_devices; i++)
            {
                if ( NULL != pUsbCore->class_device[i].query_func_wk_status &&
                     pUsbCore->class_device[i].query_func_wk_status(i) & 0x0002 )
                {
                    pBuffer[0] |= ((kal_uint8)0x01 << 1);
                    break;
                }
            }
        }
		else
		{
            // USB 3.0 U1 enable status (0 in USB 2.0)
            if ( pUsbCore->is_device_u1_enable )
            {
                pBuffer[0] |= ((kal_uint8)0x01 << 2);
            }

            // USB 3.0 U2 enable status ( 0 in USB 3.0)
            if( pUsbCore->is_device_u2_enable )
            {
                pBuffer[0] |= ((kal_uint8)0x01 << 3);
            }

            // USB 3.0 LTM enable status ( 0 in USB 3.0)
            if( pUsbCore->is_device_ltm_enable )
            {
                pBuffer[0] |= ((kal_uint8)0x01 << 4);
            }
		}

    } else
    if ( bRecip == USBC_REQUEST_RECIP_INTERFACE )
    {
        kal_uint8 nInterface = (kal_uint8)pUsbCore->setup_packet.wIndex;
        kal_uint8 class_device_id = pUsbCore->class_interface[nInterface].class_device_id;

        /* return two bytes of 0x00, 0x00.
           Both bytes are reserved for future use
         */
        pBuffer[0] = 0;
        pBuffer[1] = 0;
        length = 2;
        type = USBC_CONTROL_REQUEST_TYPE_SEND;

        if ( pUsbCore->speed == USBC_USB_SPEED_USB30 &&
             usbc_core_is_1st_interface(nInterface)  &&
             NULL !=  pUsbCore->class_device[class_device_id].query_func_wk_status )
        {
            /* if the requested interface is the first one of a function,
               report the function remote wakeup capability and state
             */
            pBuffer[0] = pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) & ((kal_uint8)0xFF);
        }

    } else
    if ( bRecip == USBC_REQUEST_RECIP_ENDPOINT )
    {
        /* D0: HALT, D1: Reserve */
        kal_uint8 nEnd = pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_NUM_MASK; /* TODO: It's error-prone to use en_no instead of endpoint address. */
        usbc_core_queue_t* pQueue = NULL;
        kal_uint8 i = 0;

        if ( (pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_DIR_IN) )
        {
            for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
            {
                if ( (pUsbCore->tx_queue[i].ep_no == nEnd) &&
                     (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
                {
                    pQueue = &pUsbCore->tx_queue[i];
                    break;
                }
            }
        } else {
            for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
            {
                if ( (pUsbCore->rx_queue[i].ep_no == nEnd) &&
                     (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
                {
                    pQueue = &pUsbCore->rx_queue[i];
                    break;
                }
            }
        }

        /* D0: HALT, D1: Reserve */
        if ( pQueue == NULL )
        {
            length = 0;
            type = USBC_CONTROL_REQUEST_TYPE_STALL;

            if( nEnd == 0)
            {
                pBuffer[0] = 0;
                pBuffer[1] = 0;
                length = 2;
                type = USBC_CONTROL_REQUEST_TYPE_SEND;
            }

        } else {
            switch (pQueue->state)
            {
                case USBC_CORE_QUEUE_STATE_ACTIVE:
                {
                    pBuffer[0] = 0;
                    pBuffer[1] = 0;
                    length = 2;
                    type = USBC_CONTROL_REQUEST_TYPE_SEND;
                    break;
                }
                case USBC_CORE_QUEUE_STATE_STALL:
                {
                    pBuffer[0] = 1;
                    pBuffer[1] = 0;
                    length = 2;
                    type = USBC_CONTROL_REQUEST_TYPE_SEND;
                    break;
                }
                default:
                {
                    ASSERT(0);
                    length = 0;
                    type = USBC_CONTROL_REQUEST_TYPE_STALL;
                    break;
                }
            }
        }
    } else {
        ASSERT(0);
        type = USBC_CONTROL_REQUEST_TYPE_STALL;
    }

    usbc_core_set_control_request(pBuffer, length, type);

}