예제 #1
0
/*
 * Todo replace this call by Asynchronous/Non Blocking
 * */
int ANDROID_read(t_AndroidInstance handle, t_u8* const buff/*out*/, const int len/*in*/)
{
    t_u16 i, nbdata;
    t_u32 ulBytes;
    t_USBHANDROIDInstance *pANDROIDDevice;

    // Get a pointer to the device instance data from the handle.
    pANDROIDDevice = (t_USBHANDROIDInstance *)handle;
    if(pANDROIDDevice != NULL)
    {
        /*
        * TODO use asynchronous transfer maybe to have better performance ...
        */
        /*
        if(rx_data_available == 0)
        {
            ulBytes = USBHCDPipeSchedule(g_USBHANDROIDDevice.ulBulkInPipe, (unsigned char*)buff, len);
            rx_data_available = len;
        }
        ulBytes = USBHCDPipeReadNonBlocking(g_USBHANDROIDDevice.ulBulkInPipe, (unsigned char*)buff, len);
        rx_data_available = rx_data_available - ulBytes;
        */
        
        /* Workaround code to ensure data are received and are not equal to 0.
        *  because USBHCDPipeRead() sometimes return size >0 (when timeout) even if there is no new data.
        * */
        for(i=0; i<len; i++)
        {
            buff[i] = 0;
        }
        nbdata = 0;
        ulBytes = USBHCDPipeRead(pANDROIDDevice->ulBulkInPipe, (unsigned char*)buff, len);
        for(i=0; i<len; i++)
        {
            if(buff[i] != 0)
            nbdata++;
        }
        // Data have not changed assume no data received
        if(nbdata == 0)
            ulBytes = 0;
    }
    else
    {
        /* Error invalid handle */
        ulBytes = 0;
    }
    
    return ulBytes;
}
예제 #2
0
파일: usbhscsi.c 프로젝트: mybays/lm3s
//*****************************************************************************
//
//! This function is used to issue SCSI commands via USB.
//!
//! \param ulInPipe is the USB IN pipe to use for this command.
//! \param ulOutPipe is the USB OUT pipe to use for this command.
//! \param pSCSICmd is the SCSI command structure to send.
//! \param pucData is pointer to the command data to be sent.
//! \param pulSize is the number of bytes is the number of bytes expected or
//! sent by the command.
//!
//! This internal function is used to handle SCSI commands sent by other
//! functions.  It serves as a layer between the SCSI command and the USB
//! interface being used to send the command.  The \e pSCSI parameter contains
//! the SCSI command to send.  For commands that expect data back, the
//! \e pucData is the buffer to store the data into and \e pulSize is used to
//! store the amount of data to request as well as used to indicate how many
//! bytes were filled into the \e pucData buffer on return.  For commands that
//! are sending data, \e pucData is the data to be sent and \e pulSize is the
//! number of bytes to send.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
static unsigned long
USBHSCSISendCommand(unsigned long ulInPipe, unsigned long ulOutPipe,
                    tMSCCBW *pSCSICmd, unsigned char *pucData,
                    unsigned long *pulSize)
{
    tMSCCSW CmdStatus;
    unsigned long ulBytes;

    //
    // Initialize the command status.
    //
    CmdStatus.dCSWSignature = 0;
    CmdStatus.dCSWTag = 0;
    CmdStatus.bCSWStatus = SCSI_CMD_STATUS_FAIL;

    //
    // Set the CBW signature and tag.
    //
    pSCSICmd->dCBWSignature = CBW_SIGNATURE;
    pSCSICmd->dCBWTag = CBW_TAG_VALUE;

    //
    // Set the size of the data to be returned by the device.
    //
    pSCSICmd->dCBWDataTransferLength = *pulSize;

    //
    // Send the command.
    //
    ulBytes = USBHCDPipeWrite(ulOutPipe,
                              (unsigned char*)pSCSICmd, sizeof(tMSCCBW));

    //
    // If no bytes went out then the command failed.
    //
    if(ulBytes == 0)
    {
        return(SCSI_CMD_STATUS_FAIL);
    }

    //
    // Only request data if there is data to request.
    //
    if(pSCSICmd->dCBWDataTransferLength != 0)
    {
        //
        // See if this is a read or a write.
        //
        if(pSCSICmd->bmCBWFlags & CBWFLAGS_DIR_IN)
        {
            //
            // Read the data back.
            //
            *pulSize = USBHCDPipeRead(ulInPipe, pucData, *pulSize);
        }
        else
        {
            //
            // Write the data out.
            //
            *pulSize = USBHCDPipeWrite(ulOutPipe, pucData, *pulSize);
        }
    }

    //
    // Get the status of the command.
    //
    ulBytes = USBHCDPipeRead(ulInPipe, (unsigned char *)&CmdStatus,
                             sizeof(tMSCCSW));


    //
    // If the status was invalid or did not have the correct signature then
    // indicate a failure.
    //
    if((ulBytes == 0) || (CmdStatus.dCSWSignature != CSW_SIGNATURE) ||
       (CmdStatus.dCSWTag != CBW_TAG_VALUE))
    {
        return(SCSI_CMD_STATUS_FAIL);
    }

    //
    // Return the status.
    //
    return((unsigned long)CmdStatus.bCSWStatus);
}
예제 #3
0
//*****************************************************************************
//
//! This function is used to issue SCSI commands via USB.
//!
//! \param ui32InPipe is the USB IN pipe to use for this command.
//! \param ui32OutPipe is the USB OUT pipe to use for this command.
//! \param psSCSICmd is the SCSI command structure to send.
//! \param pui8Data is pointer to the command data to be sent.
//! \param pui32Size is the number of bytes is the number of bytes expected or
//! sent by the command.
//!
//! This internal function is used to handle SCSI commands sent by other
//! functions.  It serves as a layer between the SCSI command and the USB
//! interface being used to send the command.  The \e pSCSI parameter contains
//! the SCSI command to send.  For commands that expect data back, the
//! \e pui8Data is the buffer to store the data into and \e pui32Size is used
//! to store the amount of data to request as well as used to indicate how many
//! bytes were filled into the \e pui8Data buffer on return.  For commands that
//! are sending data, \e pui8Data is the data to be sent and \e pui32Size is
//! the number of bytes to send.
//!
//! \return This function returns the SCSI status from the command.  The value
//! will be either \b SCSI_CMD_STATUS_PASS or \b SCSI_CMD_STATUS_FAIL.
//
//*****************************************************************************
static uint32_t
USBHSCSISendCommand(uint32_t ui32InPipe, uint32_t ui32OutPipe,
                    tMSCCBW *psSCSICmd, uint8_t *pui8Data, uint32_t *pui32Size)
{
    tMSCCSW sCmdStatus;
    uint32_t ui32Bytes;

    //
    // Initialize the command status.
    //
    writeusb32_t(&(sCmdStatus.dCSWSignature), 0);
    writeusb32_t(&(sCmdStatus.dCSWTag), 0);
    sCmdStatus.bCSWStatus = SCSI_CMD_STATUS_FAIL;

    //
    // Set the CBW signature and tag.
    //
    writeusb32_t(&(psSCSICmd->dCBWSignature), CBW_SIGNATURE);
    writeusb32_t(&(psSCSICmd->dCBWTag), CBW_TAG_VALUE);

    //
    // Set the size of the data to be returned by the device.
    //
    writeusb32_t(&(psSCSICmd->dCBWDataTransferLength), *pui32Size);

    //
    // Send the command.
    //
    ui32Bytes = USBHCDPipeWrite(ui32OutPipe, (uint8_t*)psSCSICmd,
                                sizeof(tMSCCBW));

    //
    // If no bytes went out then the command failed.
    //
    if(ui32Bytes == 0)
    {
        return(SCSI_CMD_STATUS_FAIL);
    }

    //
    // Only request data if there is data to request.
    //
    if(readusb32_t(&(psSCSICmd->dCBWDataTransferLength)) != 0)
    {
        //
        // See if this is a read or a write.
        //
        if(psSCSICmd->bmCBWFlags & CBWFLAGS_DIR_IN)
        {
            //
            // Read the data back.
            //
            *pui32Size = USBHCDPipeRead(ui32InPipe, pui8Data, *pui32Size);
        }
        else
        {
            //
            // Write the data out.
            //
            *pui32Size = USBHCDPipeWrite(ui32OutPipe, pui8Data, *pui32Size);
        }
    }

    //
    // Get the status of the command.
    //
    ui32Bytes = USBHCDPipeRead(ui32InPipe, (uint8_t *)&sCmdStatus,
                               sizeof(tMSCCSW));


    //
    // If the status was invalid or did not have the correct signature then
    // indicate a failure.
    //
    if((ui32Bytes == 0) || (readusb32_t(&(sCmdStatus.dCSWSignature)) != CSW_SIGNATURE) ||
       (readusb32_t(&(sCmdStatus.dCSWTag)) != CBW_TAG_VALUE))
    {
        return(SCSI_CMD_STATUS_FAIL);
    }

    //
    // Return the status.
    //
    return((uint32_t)sCmdStatus.bCSWStatus);
}