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

📄 usb-pxa250.c

📁 PXA250上的XBOOT
💻 C
字号:
/* * $Id: usb-pxa250.c,v 1.10 2003/09/24 12:13:35 jfabo Exp $ * * Copyright (C) 2002, 2003 ETC s.r.o. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * Written by Daniel Samek <dano@etc.sk>, 2002. * 		Juraj Fabo <vinco@etc.sk>, 2003. *  */#include <.config.h>#include "board.h"#if CPU == PXA250#include <_windows.h>#include "download.h"#include "format.h"#if defined(USB_VID) && defined(USB_PID)#include <pxa2x0/gpio.h>#include <pxa2x0/udc.h>#include <pxa2x0/pmrc.h>#include "except.h"#include "usb.h"#include "splash.h"#define UDCCR_FLAGS	(UDCCR_RSTIR | UDCCR_SUSIR | UDCCR_RESIR | UDCCR_RSM)#define UDCCR_SET(x)	UDCCR = (UDCCR & (~UDCCR_FLAGS)) | x#define UDCCR_CLEAR(x)  UDCCR = UDCCR & (~(UDCCR_FLAGS | x))#define UDCCS0_FLAGS	(UDCCS0_OPR | UDCCS0_IPR | UDCCS0_SST | UDCCS0_FST | UDCCS0_SA)#define UDCCS0_SET(x)	UDCCS0 = (UDCCS0 & (~UDCCS0_FLAGS)) | x#define UDCCS1_FLAGS    (UDCCS1_TPC | UDCCS1_FTF | UDCCS1_TUR | UDCCS1_SST | UDCCS1_TSP)#define UDCCS1_SET(x)   UDCCS1 = (UDCCS1 & (~UDCCS1_FLAGS)) | x#define UDCCS2_FLAGS      (UDCCS2_RPC | UDCCS2_SST)#define UDCCS2_SET(x)     UDCCS2 = (UDCCS2 & (~UDCCS2_FLAGS)) | x#define UDCCS2_CLEAR(x)   UDCCS2 = UDCCS2 & (~(UDCCS2_FLAGS | x))#define SETUP_MAXPACKET	8#define EP0_MAXPACKET	16#define EP1_MAXPACKET	64#define EP2_MAXPACKET	64static const struct usb_dev_desc wep_dev_desc = {	18,					/* length */	1,					/* descriptortype */	0x0110,					/* usb */	-1,					/* deviceclass */	-1,					/* devicesubclass */	-1,					/* deviceprotocol */	EP0_MAXPACKET,				/* maxpacketsize */	USB_VID,				/* idvendor */	USB_PID,				/* idproduct */	0,					/* device */	0,					/* manufacturer */	0,					/* product */	0,					/* serialnumber */	1,					/* numconfigurations */};static const struct usb_conf_desc wep_conf_desc = {	{				9,		/* length */				2,		/* descriptortype (CONFIGURATION) */				32,		/* total length */				1,		/* numinterfaces */				1,		/* configurationvalue */				0,		/* configuration */				-64,		/* attributes */				0,		/* maxpower */			}	,	{				9,		/* length */				4,		/* descriptortype (INTERFACE) */				0,		/* interfacenumber */				0,		/* alternatesetting */				2,		/* numendpoints */				-1,		/* interfaceclass */				-1,		/* interfacesubclass */				-1,		/* interfaceprotocol */				0,		/* interface */			}	,	{				7,		/* length */				5,		/* descriptortype (ENDPOINT) */				-127,		/* endpointaddress (ep1, in) */				0x02,		/* attributes (0010 = bulk) */				EP1_MAXPACKET,	/* maxpacketsize */				0,		/* interval (ignored for bulk) */			}	,	{				7,		/* length */				5,		/* descriptortype (ENDPOINT) */				0x02,		/* endpointaddress (ep2, out) */				0x02,		/* attributes (0010 = bulk) */				EP2_MAXPACKET,	/* maxpacketsize */				0,		/* interval (ignored for bulk) */			}};#define EP0_IDLE		1#define EP0_IN_DATA_PHASE	2#define EP0_WAIT_XFER		3#define EP0_END_XFER		4static int status;static int index;static int length;static unsigned char *packet;static int get_descriptor_flag;static int usb_ready;static intusbcable_wait( void ){	int i,	  in;	uint32_t timeout = 0;	EdbgOutputDebugString( "* Please connect USB cable between PC and wep.\n" );	for (i = 9, in = 0; i && !in; i--) {		EdbgOutputDebugString( "%d\r", i );		for (timeout = 0x200000; timeout; timeout--)			if (GPLR0 & GPIO0_GP11) {				in = 1;				break;			}	}	return timeout ? 1 : 0;}static intusbcable_in( void ){	if (GPLR0 & GPIO0_GP11)		return 1;	UDCCR_CLEAR( UDCCR_UDE );		/* disable UDC */	/* high speed usb device disable */	GPDR2 &= ~GPIO2_GP79;	return 0;}static intget_descriptor( struct usb_dev_req *req ){	switch (req->value_hi) {		case 1:			/* device descriptor */			length = sizeof (struct usb_dev_desc);			if (req->length < length) {				EdbgOutputDebugString( "device decriptor is short: %d\n", req->length );				return 0;			}			index = 0;			packet = (unsigned char *) &wep_dev_desc;			return 1;		case 2:			/* configuration descriptor */			length = sizeof (struct usb_conf_desc);			if (req->length < length)				length = req->length;			index = 0;			packet = (unsigned char *) &wep_conf_desc;			return 1;		default:			EdbgOutputDebugString( "unknown descriptor: %d\n", req->value_hi );			return 0;	}}static intset_configuration( void ){	UICR0 &= ~UICR0_IM2;			/* enable ep2 interrupt */	UDCCS2_CLEAR( UDCCS2_DME );	usb_ready = 1;	return 1;}static intstandard_request( struct usb_dev_req *req ){	switch (req->request) {		case 6:			/* get descriptor */			get_descriptor_flag = get_descriptor( req );			return get_descriptor_flag;		case 9:			/* set configuration */			return set_configuration();		default:			EdbgOutputDebugString( "unknown standard request: %d\n", req->request );			return 0;	}}static intclass_request( struct usb_dev_req *req ){	switch (req->request) {		case 34:			/* set control line state */			index = length = 0;			return 1;		default:			EdbgOutputDebugString( "unknown class request: %d\n", req->request );			return 0;	}}static intparse_command( struct usb_dev_req *req ){	unsigned char req_type;	req_type = (unsigned char) req->m_request;	req_type >>= 5;	req_type &= 0x3;	switch (req_type) {		case 0:			/* standard request */			return standard_request( req );		case 1:			/* class request */			return class_request( req );		default:			EdbgOutputDebugString( "unknown request type: 0x%X\n", req->m_request );			return 0;	}}static intep0_idle( void ){	unsigned char out_packet[SETUP_MAXPACKET] ;	int setup_command_valid;	int i;	index = -1;	if (!((UDCCS0 & UDCCS0_SA) && (UDCCS0 & UDCCS0_OPR))) {		EdbgOutputDebugString( "SA & OPR not set: UDCCS0: 0x%X\n", UDCCS0 );		return 0;	}	if (UDCCS0 & UDCCS0_RNE) {		for (i = 0; (i < SETUP_MAXPACKET) && (UDCCS0 & UDCCS0_RNE); i++)			out_packet[i] = (unsigned char) UDDR0;		if (i < SETUP_MAXPACKET) {			EdbgOutputDebugString( "short out packet: %d\n", i );			return 0;		}	} else					/* errata 131 */		for (i = 0; i < SETUP_MAXPACKET; i++)			out_packet[i] = (unsigned char) UDDR0;	setup_command_valid = parse_command( (struct usb_dev_req *) out_packet );	if (index != -1) {			/* no data */		for (i = 0; (i < EP0_MAXPACKET) && (index < length); i++, index++)			UDDR0 = (unsigned char) packet[index];		status = EP0_IN_DATA_PHASE;	}	UDCCS0_SET( UDCCS0_SA | UDCCS0_OPR );	if (!setup_command_valid) {		status = EP0_IDLE;		get_descriptor_flag = 0;		/* stall */		UDCCS0_SET( UDCCS0_FST );		while (!(UDCCS0 & UDCCS0_SST)) ;		UDCCS0_SET( UDCCS0_SST );		return 1;	}	if (index == -1)			/* no data */		return 1;	if (i < EP0_MAXPACKET) {		status = EP0_END_XFER;		get_descriptor_flag = 0;		UDCCS0_SET( UDCCS0_IPR );		return 1;	}	if (index == length) {		status = EP0_WAIT_XFER;		get_descriptor_flag = 0;		UDCCS0_SET( UDCCS0_IPR );	}	return 1;}static intep0_in_data_phase( void ){	int i;	if (get_descriptor_flag && (UDCCS0 & UDCCS0_OPR) && (!(UDCCS0 & UDCCS0_SA))) {	/* premature											   status stage */		UDCCS0_SET( UDCCS0_OPR );		status = EP0_IDLE;		get_descriptor_flag = 0;		UDCCS0_SET( UDCCS0_FTF );		return 1;	}	if (index == length) {		EdbgOutputDebugString( "no data\n" );		return 0;	}	for (i = 0; (i < EP0_MAXPACKET) && (index < length); i++, index++)		UDDR0 = (unsigned char) packet[index];	if (i < EP0_MAXPACKET) {		status = EP0_END_XFER;		get_descriptor_flag = 0;		UDCCS0_SET( UDCCS0_IPR );		return 1;	}	if (index == length) {		status = EP0_WAIT_XFER;		get_descriptor_flag = 0;		UDCCS0_SET( UDCCS0_IPR );	}	return 1;}static intep0_wait_xfer(){	UDCCS0_SET( UDCCS0_IPR );	status = EP0_END_XFER;	return 1;}static intep0_end_xfer(){	if ((UDCCS0 & UDCCS0_OPR) && (!(UDCCS0 & UDCCS0_SA))) {		UDCCS0_SET( UDCCS0_OPR );		status = EP0_IDLE;		get_descriptor_flag = 0;	}	return 1;}static voidep0_intr( void ){	int retval = 0;	while (!retval) {		/* new setup command */		if ((UDCCS0 & UDCCS0_SA) && (UDCCS0 & UDCCS0_OPR)) {			status = EP0_IDLE;			get_descriptor_flag = 0;		}		switch (status) {			case EP0_IDLE:				retval = ep0_idle();				break;			case EP0_IN_DATA_PHASE:				retval = ep0_in_data_phase();				break;			case EP0_WAIT_XFER:				retval = ep0_wait_xfer();				break;			case EP0_END_XFER:				retval = ep0_end_xfer();				break;			default:				EdbgOutputDebugString( "unknown status: %d\n", status );		}	}	USIR0 = USIR0_IR0;}static intusb_init( void ){	status = EP0_IDLE;	get_descriptor_flag = 0;	usb_ready = 0;	UDCCR_SET( UDCCR_UDE );			/* enable UDC */#ifdef	CONFIG_EP250_B1_B2	/* FIXME: turn off double buffer for ep0 and ep1 (intel driver) */	((volatile uint32_t *) UDC_pointer)[1] &= ~0x06;#endif	if (UDCCR & UDCCR_UDA)		UICR0 &= ~UICR0_IM0;		/* enable ep0 interrupt */	else		UDCCR_SET( UDCCR_RSTIR );	/* high speed usb device enable */	GPSR2 = GPIO2_GP79;	GPDR2 |= GPIO2_GP79;	while (!usb_ready) {		if (!usbcable_in())			break;		if (UDCCR & UDCCR_RSTIR) {	/* reset */			UDCCR_SET( UDCCR_RSTIR );			if (UDCCR & UDCCR_UDA) {				UICR0 &= ~UICR0_IM0;	/* enable ep0 interrupt */				status = EP0_IDLE;				get_descriptor_flag = 0;			}			continue;		}		/* endpoint 0 */		if ((!(UICR0 & UICR0_IM0)) && (USIR0 & USIR0_IR0))			ep0_intr();	}	return usb_ready;}static voidusb_write_maxpack( char *buff){	uint32_t timeout;	int i = 0;	if (!usb_ready)		Throw E_USBUNINITIALIZED;	/* process control command */	while (USIR0 & USIR0_IR0)		ep0_intr();	/* copy data from buffer to FIFO */	for (i = 0; i < EP1_MAXPACKET; i++) {		UDDR1 = buff[i] & 0xFF;	}	if (i < EP1_MAXPACKET)		UDCCS1_SET( UDCCS1_TSP | UDCCS1_TPC );	else		UDCCS1_SET( UDCCS1_TPC );	UICR0 &= ~UICR0_IM1;			/* enable ep1 interrupt */	for (timeout = 0x200000; timeout; timeout--)		if (USIR0 & USIR0_IR1)			break;	UICR0 |= UICR0_IM1;			/* disable ep1 interrupt */	USIR0 = USIR0_IR1;			/* clear ep1 interrupt */	if (!timeout)		Throw E_WRITETIMEOUT;}static voidusb_write_terminate(){	uint32_t timeout;	if (!usb_ready)		Throw E_USBUNINITIALIZED;	/* process control command */	while (USIR0 & USIR0_IR0)		ep0_intr();	UDCCS1_SET( UDCCS1_TSP );	UDCCS1_SET( UDCCS1_TPC );	UICR0 &= ~UICR0_IM1;			/* enable ep1 interrupt */	for (timeout = 0x200000; timeout; timeout--)		if (USIR0 & USIR0_IR1)			break;	UICR0 |= UICR0_IM1;			/* disable ep1 interrupt */	USIR0 = USIR0_IR1;			/* clear ep1 interrupt */	if (!timeout)		Throw E_WRITETIMEOUT;	}static voidusb_writechar( char c ){	uint32_t timeout;	if (!usb_ready)		Throw E_USBUNINITIALIZED;	/* process control command */	while (USIR0 & USIR0_IR0)		ep0_intr();	UDDR1 = c & 0xFF;	UDCCS1_SET( UDCCS1_TSP );	UDCCS1_SET( UDCCS1_TPC );	UICR0 &= ~UICR0_IM1;			/* enable ep1 interrupt */	for (timeout = 0x200000; timeout; timeout--)		if (USIR0 & USIR0_IR1)			break;	UICR0 |= UICR0_IM1;			/* disable ep1 interrupt */	USIR0 = USIR0_IR1;			/* clear ep1 interrupt */	if (!timeout)		Throw E_WRITETIMEOUT;}#define MIN(a,b)	(a < b) ? a : bstatic charusb_read( unsigned char *buff, int len ){	static int buffer_index = 0, fifo_top = 0;	static unsigned char buffer[EP2_MAXPACKET];	uint32_t timeout;	int minimum;	minimum = MIN(buffer_index, len);	if (buffer_index) {		memcpy(buff, buffer + fifo_top - buffer_index, minimum);	}		len -= minimum;	buffer_index -= minimum;	if (!len) {		return 1;	}	if (!usb_ready)		Throw E_USBUNINITIALIZED;	while (len) {		for (timeout = 0x200000; timeout; timeout--)			if ((USIR0 & USIR0_IR2) && (UDCCS2 & UDCCS2_RNE))				break;		if (!timeout) {			Throw E_READTIMEOUT;		}		while (UDCCS2 & UDCCS2_RNE) {			buffer[buffer_index++] = (char) (UDDR2 & 0xFF);		}		fifo_top = buffer_index;		if (!(UDCCS2 & UDCCS2_RNE)) {			UDCCS2_SET( UDCCS2_RPC );			USIR0 = USIR0_IR2;		}		buff += minimum;		minimum = MIN(buffer_index, len);		if (buffer_index) {			memcpy(buff, buffer + fifo_top - buffer_index, minimum);		}			len -= minimum;		buffer_index -= minimum;	}	return 1;}int USB_upload( void ){	unsigned int i, upload_start = 0, upload_end = 0;	unsigned int size = 0;#ifdef CONFIG_SPLASH_SCREEN	unsigned char progress_percentage = 0;	uint32_t total_len = 0;#endif	int e;	/* exception	*/	Try {		usb_read(&((unsigned char)(upload_start)), 4);		usb_read(&((unsigned char)(size)), 4);		upload_end = upload_start + size;	} Catch(e) {		EdbgOutputDebugString("exception %d",e);	}	EdbgOutputDebugString("\nSynchronized, starting data transfer from: 0x%x to 0x%x\n", upload_start, upload_end);	upload_start += MEM_VIRT_FLASH;	upload_end += MEM_VIRT_FLASH;	i = upload_start;	while (i < upload_end) {		Try {			for (i = upload_start; i < upload_end; i += 64 ) {				usb_write_maxpack((char *)(i));#ifdef CONFIG_SPLASH_SCREEN				total_len += 64;				if (((total_len * 100 )/size ) > progress_percentage ){					progress_percentage = (unsigned char)((total_len * 100 )/ size );					progress_bar(progress_percentage, 1);				}#endif								}		} Catch(e) {			EdbgOutputDebugString("exception %d\n",e);		}	}#ifdef	CONFIG_EP250_C0_A0	usb_write_terminate();#endif	usb_write_terminate();#ifdef CONFIG_SPLASH_SCREEN				progress_bar(100, 1);#endif		return -2;}	intUSB_download( struct imginfo *img ){	int i;	int e;	/* exception */	struct fntable fn = {		usb_writechar,		usb_read	};	int retval = -2;	int upload = 0;	/* init usb hw connection. See: 12.4 UDC Hardware Connection */	GPDR0 &= ~GPIO0_GP11;	GPDR2 &= ~GPIO2_GP79;	EdbgOutputDebugString( "Ready to download image via USB\n" );	if (!usbcable_wait() || !usb_init())		return retval;	EdbgOutputDebugString( "\nUSB ready.\n" );	for (i = 0; i < 10; i++) {		EdbgOutputDebugString( "." );		Try {			download( &fn, img, 0 );			retval = 0;		}		Catch(e) {			if (e == E_UPLOADREQUEST) {				i = 10;				upload = retval = 1;			} else				continue;		};		if (upload) {			USB_upload();		}		UDCCR_CLEAR( UDCCR_UDE );	/* disable UDC */		/* high speed usb device disable */		GPDR2 &= ~GPIO2_GP79;		return retval;	}	EdbgOutputDebugString( "\nFail to synchonize with the host\n" );	UDCCR_CLEAR( UDCCR_UDE );		/* disable UDC */	/* high speed usb device disable */	GPDR2 &= ~GPIO2_GP79;	return retval;}#else /* defined(USB_VID) && defined(USB_PID) */intUSB_download( struct imginfo *img ){	UNREFERENCED_PARAMETER( img );	return -2;}#endif /* defined(USB_VID) && defined(USB_PID) */#endif /* CPU == PXA250 */

⌨️ 快捷键说明

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