📄 transfer.c
字号:
/*
** WASABI-Hot! version 1.2c
**
**
** -- copyright (c) 2001-2004 by Philips Japan, Ltd. -- All rights reserved --
**
**
** ** This code has been made to check/learn **
** ** the ISP1362/ISP1363 functionalities **
** ** Release 06-Aug-2004 **
**
** OKANO, Akifumi
**
** Application Laboratory, Mobile and Connectivity
** Semiconductors Div, Philips Japan Ltd.
** akifumi.okano@philips.com
** +81-3-3740-4668
*/
/****************************************************************************/
/* includes */
/****************************************************************************/
#include <stdio.h>
#include "_hc_core/atl_mix.h"
#include "_hc_core/transfer.h"
#include "_hc_hw/hc_comm.h"
#include "_hc_hw/hw_acces.h"
#include "ui.h"
#include "general.h"
/****************************************************************************/
/* constants */
/****************************************************************************/
#define CONTROL_TRANSFER_TIMEOUT_LIMIT 300 // 50ms : control transfer timeout, no response from device
//#define CONTROL_TRANSFER_TIMEOUT_LIMIT 50 // 50ms : control transfer timeout, no response from device
#define CONTROL_TRANSFER_RETRY_LIMIT 1
#define CONTROL_TRANSFER_DATA_STAGE_RETRY_LIMIT 10
/****************************************************************************/
/* global vars */
/****************************************************************************/
unsigned char g_tr_done_flag;
/****************************************************************************/
/* function prototypes */
/****************************************************************************/
void callback_control_transaction( endpoint_info_ptr epi_ptr );
/****************************************************************************/
/* function definitions */
/****************************************************************************/
/********************************************/
/* Control trnsfer */
/* */
/********************************************/
unsigned short transfer_control_transfer( USB_Device_Request *dev_req, device_instance *dvi_ptr, unsigned char *data_ptr )
{
/*
** returns
**
** error @ SETUP 0x-0--
** error @ DataStage 0x-1--
** error @ StatusStage 0x-2--
** error @ CC 0x--CC (CC=value 0x01-0x0D)
** retry over 0x--FF
** data short 0x8000 | (0x7FFF & DataLength) (DataLength =received data length) DataLength can hold
** 2^15-1 data length information. This may not be a problem.
** USB requires to have 2^16-1 but it may not happen in actual
** application.
*/
endpoint_info *epi_ptr;
unsigned short err;
unsigned short short_packet_flag = 0;
unsigned char device_to_host_transfer;
unsigned char *ds_data_ptr;
unsigned short ds_size;
unsigned short total_ds_done_size;
unsigned char ss_data_ptr[ 1 ]; // dummy
unsigned short ss_size;
unsigned short transfer_size;
unsigned short max_PTD_payload_size;
unsigned char control_tr_retry_count = 0;
unsigned char data_stage_retry_count = 0;
epi_ptr = dvi_ptr->epi_ptr[ EpOUT ][ 0 ]; // EpOUT index holds information for control EP
device_to_host_transfer = dev_req->bmRequestType >> 7;
transfer_size = dev_req->wLength;
max_PTD_payload_size = read_register16( Com16_HcATLBlkSize );
while ( control_tr_retry_count++ < CONTROL_TRANSFER_RETRY_LIMIT )
{
/********* SETUP STAGE *********/
testprint( YELLOW, "#" );
ds_size = 8; // SETUP payload size is always 8
err = transfer_control_transaction( SETUP, (unsigned char *)dev_req, &ds_size, epi_ptr );
if ( err == 0x4 )
continue;
if ( err )
{
if ( err == 0xFF )
return ( 0xFFFF );
// mprintf( LIGHTRED, CONTINUE, " control transfer terminated (SETUP failed). err = 0x%04X\r\n", err );
return ( err | 0x0000 );
}
testprint( YELLOW, "*" );
/********* DATA STAGE *********/
if ( transfer_size )
{
epi_ptr->toggle = 1; // force DT <- 1 (defined in standard)
ds_data_ptr = data_ptr;
total_ds_done_size = 0;
do
{
testprint( WHITE, "#" );
ds_size = transfer_size - total_ds_done_size;
ds_size = ds_size > max_PTD_payload_size ? max_PTD_payload_size : ds_size;
err = transfer_control_transaction( (device_to_host_transfer ? IN : OUT), ds_data_ptr, &ds_size, epi_ptr );
if ( err == 0x4 )
break;
if ( err == 0x9 ) // It is short packet
{
err = 0x8000 | (total_ds_done_size + ds_size); // Set a short packet flag
short_packet_flag = 0x8000 | (total_ds_done_size + ds_size); // Set a short packet flag
break; // and exit from this loop. Go to status stage.
}
if ( err ) // Terminate ControlTransfer sequence by non-zero or non-0x9
{
if ( err == 0xFF )
return ( 0xFFFF );
return ( err | 0x0100 );
}
if ( ds_size == 0 )
{
if ( data_stage_retry_count++ > CONTROL_TRANSFER_DATA_STAGE_RETRY_LIMIT )
{
err = 0x4;
break;
}
}
total_ds_done_size += ds_size;
ds_data_ptr += ds_size;
wait_ms( 0L );
testprint( WHITE, "*" );
}
while ( total_ds_done_size < transfer_size );
}
if ( err == 0x4 )
continue;
/********* STAUS STAGE *********/
testprint( CYAN, "#" );
epi_ptr->toggle = 1; // force DT <- 1 (defined in standard)
ss_size = 0; // must be 0
err = transfer_control_transaction( (device_to_host_transfer ? OUT : IN), ss_data_ptr, &ss_size, epi_ptr );
if ( err == 0x4 )
continue;
if ( err )
{
if ( err == 0xFF )
return ( 0xFFFF );
return ( err | 0x0200 );
}
testprint( CYAN, "*" );
break;
}
// mprintf( WHITE, CONTINUE, "transfer_control_transfer -- done \r\n" );
return ( err ? err : short_packet_flag );
}
unsigned char transfer_control_transaction( unsigned char direction, unsigned char *data_ptr, unsigned short *size_ptr, endpoint_info_ptr epi_ptr )
{
transfer_instance *tr_instance_ptr;
unsigned long timeout_limit;
unsigned char completion_code;
unsigned char index;
if ( (NO_OPEN_ATL_TRANSFER_SLOT == (index = atlmix_get_open_transfer_index( CONTROL_TRANSFER ))) )
return ( 0xFF );
g_tr_done_flag = 0;
timeout_limit = gp_sof_counter + CONTROL_TRANSFER_TIMEOUT_LIMIT; // Set timeout value
// Start transaction
tr_instance_ptr = atlmix_set_transfer( CONTROL_TRANSFER, 0, index, data_ptr, *size_ptr, direction, epi_ptr, callback_control_transaction );
while ( !g_tr_done_flag ) // Wait in the loop. This flag will be set by callback function
{
wait_ms( 0L );
if ( timeout_limit < gp_sof_counter ) // Check timeout. Device respond to control transfer?
{
atlmix_free_transfer_index( CONTROL_TRANSFER, index ); // and abort transaction
*size_ptr = 0; // If no response within 50ms, set returned datasize to zero
return ( 0xF ); // Exit from this function with error code : "timeout"
}
}
*size_ptr = tr_instance_ptr->transferred_size;
completion_code = tr_instance_ptr->completion_code;
atlmix_free_transfer_index( CONTROL_TRANSFER, index );
return ( completion_code );
}
void callback_control_transaction( endpoint_info_ptr dummy_for_func_compatibility )
{
dummy_for_func_compatibility = dummy_for_func_compatibility; // This line for erase warning
g_tr_done_flag = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -