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

📄 storage.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 3 页
字号:

	ctrl_tr( &buffer, dvi_ptr, storage_cls_sp_request_BulkOnlyMassStorageReset, 0 );

	un_stall( IN  );
	un_stall( OUT );
}

static unsigned char ctrl_tr(  unsigned char *buffer_ptr, device_instance *dvi_ptr, unsigned short req, unsigned short length )
{
	unsigned short	err;
	unsigned short	size;
	unsigned char	i		= 0;
	
	while ( i++ < 3 )
	{
		size	= length;

		err		 = devep_std_request( buffer_ptr, dvi_ptr, req, 0, 0, &size );
		err		&= 0xF;
		
		if ( (err == 0) || (err == 4) )
			break;
	}
	
	return ( err );
}



/*
==============================================================================
==============================================================================
====	Private functions for storage drive
====		Data transfers (low level : Bulk transfers)
==============================================================================
==============================================================================
*/


static unsigned char strg_bulk_transfer( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction )
{
	unsigned char	result;
	unsigned char	i	= 0;

	do
	{
	
#ifdef USE_PAIRED_PTD

		atlmix_pp_atl_flag_mask( True );

		if ( (length > g_payload_size) && !(atlmix_pp_atl_active()) && !i )
			result	= strg_bulk_transfer_pp_once( dvi_ptr, buffer_ptr, length, direction );
		else
			result	= strg_bulk_transfer_once( dvi_ptr, buffer_ptr, length, direction );
		
		atlmix_pp_atl_flag_mask( False );
		
#else	//	USE_PAIRED_PTD
			
		result	= strg_bulk_transfer_once( dvi_ptr, buffer_ptr, length, direction );

#endif	//	USE_PAIRED_PTD

		g_cc_logger[result]++;

		if ( (result == 0xF) || (result == 0x4) )
			break;

//		mprintf( LIGHTRED, CONTINUE, "result=0x%X (%u)\r\n", result, i );
	}
	while ( i++ < 3 );
	
	return ( (result == 0xF) ? 0 : result );
}


void storage_show_cclog_result( void )
{
	unsigned char	i;
	
	mprintf( LIGHTRED, CONTINUE, "\r\n" );

	for ( i = 0; i < 16; i++ )
	{
		if ( !(i % 4) )
			mprintf( LIGHTRED, CONTINUE, "  | " );
	
		mprintf( LIGHTRED, CONTINUE, " %lu", g_cc_logger[i] );
	}
	
	
	mprintf( LIGHTRED, CONTINUE, "\r\n" );
}


static unsigned char strg_bulk_transfer_once( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction )
{
	storage_instance	*si_ptr;
	unsigned long		timeout;

	si_ptr		= (storage_instance *)(dvi_ptr->class_instance_ptr);

	si_ptr->ti_index			= atlmix_get_open_transfer_index( BULK_TRANSFER );	

	if ( NO_OPEN_ATL_TRANSFER_SLOT == si_ptr->ti_index )
	{
		atlmix_display_open_slot();
		mprintf( LIGHTRED, ABORT, "error @ strg_bulk_transfer_once, transfer list full.\r\n" );
	}
		
	si_ptr->remaining_tr_size	= length;
	si_ptr->transferred_size	= 0;
	si_ptr->transfer_stop		= False;
	si_ptr->bulk_done			= 0;
	si_ptr->buffer_ptr			= buffer_ptr;
	si_ptr->direction			= direction;

	si_ptr->tip		= start_strg_bulk_transfer( dvi_ptr );

	if ( NULL == si_ptr->tip )
	{
		/*	Error at starting transfer	*/;

		atlmix_free_transfer_index( BULK_TRANSFER, si_ptr->ti_index );	
		
		return ( error );
	}
	
	timeout			= gp_sof_counter + 500;
	
	while ( !si_ptr->bulk_done && (gp_sof_counter < timeout) )
		;
	
	si_ptr->transfer_stop		= True;

	if ( si_ptr->remaining_tr_size && !si_ptr->bulk_done )
		si_ptr->bulk_done	= 0xE;

	atlmix_free_transfer( si_ptr->tip );		/*	release the slot	*/
	si_ptr->tip		= NULL;

	return ( si_ptr->bulk_done );
}


static transfer_instance *start_strg_bulk_transfer( device_instance *dvi_ptr )
{
	transfer_instance	*transfer_inst_pointer;
	storage_instance	*si_ptr;

	si_ptr					= (storage_instance *)(dvi_ptr->class_instance_ptr);

	transfer_inst_pointer	= atlmix_set_transfer(
									BULK_TRANSFER,
									0,
									si_ptr->ti_index,
									si_ptr->buffer_ptr,
									si_ptr->remaining_tr_size,
									si_ptr->direction,
									(si_ptr->direction == OUT) ? si_ptr->endpoint_OUT : si_ptr->endpoint_IN,
									end_strg_bulk_transfer
							);

	return ( transfer_inst_pointer );	/*	Started!	*/
}


static void end_strg_bulk_transfer( endpoint_info_ptr eip )
{
	//	Callback function for the transfer (called in ISR context)								*/

	storage_instance	*si_ptr;
	transfer_instance	*tip;
	unsigned short		size;

	tip			= eip->transfer_instance;
	si_ptr		= (storage_instance *)(g_storage_device_ptr->class_instance_ptr);

	size		= tip->transferred_size;
	
	si_ptr->buffer_ptr			+= size;
	si_ptr->transferred_size	+= size;
	si_ptr->remaining_tr_size	-= size;
	
	if ( tip->completion_code )
	{
		si_ptr->bulk_done	= tip->completion_code;
		return;
	}
	

	if ( si_ptr->remaining_tr_size == 0 )
		si_ptr->bulk_done	= 0xF;	
	else if ( !si_ptr->transfer_stop )
		start_strg_bulk_transfer( g_storage_device_ptr );	//	Retry to transfer remaining data
}


//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////

#ifdef		USE_PAIRED_PTD
#define		PP_START	0xFF

static unsigned char strg_bulk_transfer_pp_once( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction )
{
	storage_instance	*si_ptr;
	unsigned long		timeout;

	si_ptr		= (storage_instance *)(dvi_ptr->class_instance_ptr);

	si_ptr->ti_index0			= atlmix_get_open_transfer_index( BULK_TRANSFER );	
	
	if ( NO_OPEN_ATL_TRANSFER_SLOT == si_ptr->ti_index0 )
		mprintf( LIGHTRED, ABORT, "error @ strg_bulk_transfer_pp_once, transfer list full.\r\n" );

	si_ptr->ti_index1			= atlmix_get_open_transfer_index( BULK_TRANSFER );	

	if ( NO_OPEN_ATL_TRANSFER_SLOT == si_ptr->ti_index1 )
	{
		atlmix_free_transfer_index( BULK_TRANSFER, si_ptr->ti_index0 );
		return ( strg_bulk_transfer_once( dvi_ptr, buffer_ptr, length, direction ) );
	}
	
	atlmix_pp_link_indexes( si_ptr->ti_index0, si_ptr->ti_index1 );

	si_ptr->remaining_tr_size	= length;
	si_ptr->transferred_size	= 0;
	si_ptr->transfer_stop		= False;
	si_ptr->bulk_done			= 0;
	si_ptr->buffer_ptr			= buffer_ptr;
	si_ptr->direction			= direction;
	
	si_ptr->tip0		= start_strg_bulk_transfer_pp( dvi_ptr, 0 | PP_START );
	si_ptr->tip1		= start_strg_bulk_transfer_pp( dvi_ptr, 1            );

	if ( (NULL == si_ptr->tip0) || (NULL == si_ptr->tip1) )
	{
		if ( NULL != si_ptr->tip0 )
			atlmix_free_transfer( si_ptr->tip0 );		/*	release the slot	*/

		if ( NULL != si_ptr->tip1 )
			atlmix_free_transfer( si_ptr->tip1 );		/*	release the slot	*/
		
		/*	Error at starting transfer	*/;
		return ( error );
	}
	
	atlmix_pp_start();

	timeout			= gp_sof_counter + 500;
	
	while ( !si_ptr->bulk_done && (gp_sof_counter < timeout) )
		;
	
	si_ptr->transfer_stop		= True;

	if ( si_ptr->remaining_tr_size && !si_ptr->bulk_done )
		si_ptr->bulk_done	= 0xE;

	atlmix_pp_unlink_indexes();

	atlmix_free_transfer( si_ptr->tip0 );		/*	release the slot	*/
	atlmix_free_transfer( si_ptr->tip1 );		/*	release the slot	*/
	si_ptr->tip0		= NULL;
	si_ptr->tip1		= NULL;

	return ( si_ptr->bulk_done );
}


static transfer_instance *start_strg_bulk_transfer_pp( device_instance *dvi_ptr, unsigned char buffer_switch )
{
	transfer_instance		*transfer_inst_pointer;
	storage_instance		*si_ptr;
	static unsigned short	written_size;

	si_ptr					= (storage_instance *)(dvi_ptr->class_instance_ptr);

	if ( buffer_switch == PP_START )
	{
		written_size	= 0;
		buffer_switch	= 0;
	}

	transfer_inst_pointer	= atlmix_set_transfer(
									BULK_TRANSFER,
									0,
									buffer_switch ? si_ptr->ti_index1 : si_ptr->ti_index0,
									si_ptr->buffer_ptr + written_size,
									g_payload_size,
									si_ptr->direction,
									(si_ptr->direction == OUT) ? si_ptr->endpoint_OUT : si_ptr->endpoint_IN,
									end_strg_bulk_transfer_pp
							);
	
	written_size	+= g_payload_size;

	return ( transfer_inst_pointer );	/*	Started!	*/
}


static void end_strg_bulk_transfer_pp( endpoint_info_ptr dummy )
{
	//	Callback function for the transfer (called in ISR context)								*/

	storage_instance	*si_ptr;
	transfer_instance	*tip;
	unsigned short		size;
	unsigned char		buffer_switch;
	
	dummy	= dummy;


	buffer_switch	= atlmix_pp_which_buffer();
	si_ptr			= (storage_instance *)(g_storage_device_ptr->class_instance_ptr);

	tip			= buffer_switch ? si_ptr->tip1 : si_ptr->tip0;
	size		= tip->transferred_size;
	
	si_ptr->transferred_size	+= size;
	si_ptr->remaining_tr_size	-= size;

	if ( tip->completion_code )		//	Error happened
	{
		si_ptr->bulk_done	= tip->completion_code;
		mprintf( WHITE, CONTINUE, "\r\nsize=%u, completion_code=%u\r\n", size, tip->completion_code );
		return;
	}

	if ( si_ptr->remaining_tr_size == 0 )
	{
		si_ptr->bulk_done	= 0xF;	
	}
	else if ( si_ptr->remaining_tr_size == g_payload_size )
	{
		//	do nothing and wait for the last transfer completion
	}
	else if ( si_ptr->remaining_tr_size < g_payload_size )
	{
		mprintf( LIGHTGRAY, CONTINUE, "???????????????????" );
	}
	else if ( !si_ptr->transfer_stop )
	{
		start_strg_bulk_transfer_pp( g_storage_device_ptr, buffer_switch );	//	Fill and start remaining data transfer
	}
}
#endif	//	USE_PAIRED_PTD


//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////

static void storage_data_dump( char *s, unsigned char *b, unsigned short n )
{
	//	Debug purpose
	
	unsigned short	i;
	
	mprintf( LIGHTGRAY, CONTINUE, "dump:%s  (%p)", s, b );

	for ( i = 0; i < n; i++ )
	{
		if ( !(i % 16) )
			mprintf( LIGHTGRAY, CONTINUE, "\r\n" );
	
		mprintf( LIGHTGRAY, CONTINUE, " %02X", *(b + i) );
	}

	mprintf( LIGHTGRAY, CONTINUE, "\r\n" );
}



/*********															*********/
/*																			*/
/*	User interface (to show the printer job status) function				*/
/*																			*/
/*		This functions is called from "ui_status_monitor()" in "ui.c" as 		*/
/*		callback function. 													*/
/*		This routine will be installed by "printer_init_commands()"	at		*/
/*		printer device enumeration.											*/
/*																			*/
/*********															*********/

void strg_status_monitor( unsigned char dummy_for_compatibility )
{
	storage_instance		*si_ptr;
	volume_param			*vpp;
	unsigned long			total_size;
	
	dummy_for_compatibility	= dummy_for_compatibility;
	
	if ( NULL == g_storage_device_ptr )
		return;
	
	si_ptr		= (storage_instance *)(g_storage_device_ptr->class_instance_ptr);
	
	if ( si_ptr->state != si_ptr->previous_state )
	{
		mprintf( BG_BLUE | WHITE    , CONTINUE, "    Storage" );
		mprintf( BG_BLUE | LIGHTGRAY, CONTINUE, "(addr %2d) : ", g_storage_device_ptr->address );

		switch ( si_ptr->state )
		{
			case IDLE :
				mprintf( BG_BLUE | LIGHTGRAY , CONTINUE, "idle... " );
				mprintf( BG_BLUE | YELLOW    , CONTINUE, "type [s] to proceed mount after media insert" );
				break;
			case WAIT_FOR_CARD :
			case WAIT_STABILIZED :
				mprintf( BG_BLUE | LIGHTRED  , CONTINUE, "%-55s", "waiting for media" );
				break;
			case MOUNT_PROCEED :
				mprintf( BG_BLUE | LIGHTRED  , CONTINUE, "%-55s", "mount processing" );
				break;
			case MOUNTED :
				{
					vpp		= (si_ptr->volume_instance)[ 0 ];
					total_size	= vpp->total_sectors * vpp->bytes_per_sector;

					mprintf( BG_BLUE | WHITE,     CONTINUE, "mounted" );
					mprintf( BG_BLUE | LIGHTGRAY, CONTINUE, "   media size = %.2lf MB            ", (double)total_size / (double)(1L << 20) );
				}
				break;
			case UNMOUNT_PROCEED :
				mprintf( BG_BLUE | LIGHTRED  , CONTINUE, "%-40s", "unmount processing" );
				break;
		}

		si_ptr->previous_state	= si_ptr->state;
	}
}





⌨️ 快捷键说明

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