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

📄 usb-sa1110.c

📁 PXA250上的XBOOT
💻 C
字号:
/*  * $Id: usb-sa1110.c,v 1.2 2003/09/17 12:20:42 jfabo Exp $ * * Copyright (C) 2001, 2002 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 Marcel Telka <marcel@telka.sk>, 2001, 2002. * */#include "board.h"#if CPU == SA1110#include <_windows.h>#include <sa11x0/gpio.h>#include <sa11x0/udc.h>#include "download.h"#include "format.h"#if defined(USB_VID) && defined(USB_PID)#include "except.h"#include "usb.h"#define	MAX_PACKET_SIZE	16#define	RETRIES		100#define	EP0_PACKET_SIZE	8/* if you want debug messages, remove this line */#define	DEBUG_OUT(s)#ifndef	DEBUG_OUT#define	DEBUG_OUT(s)	EdbgOutputDebugString(s)#define	DEBUG_OUT2(s,p)	EdbgOutputDebugString(s,p)#else#define	DEBUG_OUT2(s,p)#endif/*  * state * -1: udc not initialized *  0: default *  1: sending data via ep0 */static int state = -1;static int UDCService( void );static voidUSB_writechar( char c ){	static int first = 1;	int Timeout = 0x200000;	if (state)		Throw E_USBUNINITIALIZED;	while (Timeout--) {		UDCService();		if (!(first || (UDCCS2 & TPC)))			continue;		if (!first)			while (UDCCS2 & TPC)				UDCCS2 = TPC;		first = 0;		while (UDCIMP != 0)			UDCIMP = 0;		UDCDR = c;		while (UDCCS2 & 0x10)			UDCCS2 = 0x10;		/* SST */		return;	}	Throw E_WRITETIMEOUT;}static charUSB_read( void ){	int Timeout = 0x200000;	if (state)		Throw E_USBUNINITIALIZED;	while (Timeout--) {		UDCService();		if (!(UDCCS1 & RPC))			continue;		if (UDCCS1 & RNE)			return (char) UDCDR;		else			while (UDCCS1 & RPC)				UDCCS1 = RPC;	}	Throw E_READTIMEOUT;}/* device descriptor */static const struct usb_dev_desc wid_dev_desc = {	18,					/* length */	1,					/* descriptortype */	0x0100,					/* usb */	-1,					/* deviceclass */	-1,					/* devicesubclass */	-1,					/* deviceprotocol */	0x08,					/* maxpacketsize0 */	USB_VID,				/* idvendor */	USB_PID,				/* idproduct */	0,					/* device */	0,					/* manufacturer */	0,					/* product */	0,					/* serialnumber */	1,					/* numconfigurations */};/* configuration descriptor */static const struct usb_conf_desc wid_conf_desc = {	{				9,		/* length */				2,		/* descriptortype (CONFIGURATION) */				32,		/* total length */				1,		/* numinterfaces */				1,		/* configurationvalue */				0,		/* configuration */				0x40,		/* attributes */				1,		/* 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) */				0x01,		/* endpointaddress (ep1, out) */				2,		/* mattributes (0010 = bulk) */				MAX_PACKET_SIZE,	/* maxpacketsize */				0,		/* interval (ignored for bulk) */			}	,	{				7,		/* length */				5,		/* descriptortype (ENDPOINT) */				'\x82',		/* endpointaddress (ep2, in) */				2,		/* attributes (0010 = bulk) */				MAX_PACKET_SIZE,	/* maxpacketsize */				0,		/* interval (ignored for bulk) */			}};/* FIXME: there are more possible neverending stories. discover & solve */static voidInitUDC( void ){	UDCCR = 0;				/* enable UDC */	UDCSR = UDCSR;				/* clear all interrupts */	GPDR &= ~GPIO_USP_MASK;			/* set GPIO_USP as input */	/* TODO: add workaround with bit 7 of UDCCR for B5 stepping */	UDCIMP = MAX_PACKET_SIZE - 1;		/* set in max packet size */	UDCOMP = MAX_PACKET_SIZE - 1;		/* set out max packet size */	state = 0;}static voidDeinitUDC( void ){	UDCCR = 1;	state = -1;}static voidEP0_SendData( int start, int len, const void *d, int maxlen ){	static int index = 0;	static int reqlen = 0;	static const char *data = NULL;	unsigned int count;	if (start) {		index = 0;		if ((reqlen = len) > maxlen)			reqlen = maxlen;		data = d;		CLEAR_OPR( UDCCS0 );	}	if (index == reqlen) {		if (!(index % EP0_PACKET_SIZE)) {			SET_IPR( UDCCS0 );			index++;			DEBUG_OUT( "'" );			return;		}		index++;	}	if (index > reqlen) {		state = 0;		while (!(UDCCS0 & DE))			UDCCS0 = DE;		DEBUG_OUT( "/" );		return;	}	DEBUG_OUT( "+" );	while (UDCWC) ;				/* wait for empty FIFO */	while ((count = UDCWC) != EP0_PACKET_SIZE) {		int retries = RETRIES;		while ((count == UDCWC) && --retries)			UDCD0 = data[index];		if (!retries) {			while (!(UDCCS0 & FST))				UDCCS0 = FST;			DEBUG_OUT( "F" );			state = 0;			return;		}		if (++index == reqlen)			break;	}	SET_IPR( UDCCS0 );}static intEP0_State0( void ){	struct usb_dev_req req;	char *p = (char *) &req;	unsigned int count;	/* wait for full FIFO */	while (UDCWC != EP0_PACKET_SIZE) ;	/* read request */	while ((count = UDCWC) != 0) {		while (count == UDCWC)			*p = (char) UDCD0;		p++;	}	switch (req.request) {		case 0x05:			/* SET_ADDRESS */			CLEAR_OPR_DE( UDCCS0 );			UDCAR = req.value_lo;			UDCAR = req.value_lo;			DEBUG_OUT( "A" );			return 0;		case 0x06:			/* GET_DESCRIPTOR */			switch (req.value_hi) {				case 1:	/* DEVICE */					if (req.length == 0x12)						state = 1;					DEBUG_OUT2( "D(%d)", req.length );					EP0_SendData( 1, req.length, &wid_dev_desc,							sizeof wid_dev_desc );					return 0;				case 2:	/* CONFIGURATION */					state = 1;					DEBUG_OUT2( "C(%d)", req.length );					EP0_SendData( 1, req.length, &wid_conf_desc,							sizeof wid_conf_desc );					return 0;				default:					EdbgOutputDebugString( "EP0/GET_DESCRIPTOR/value_hi = 0x%B\n",							req.value_hi );					break;			}			break;		case 0x09:			/* SET_CONFIG */			CLEAR_OPR_DE( UDCCS0 );			DEBUG_OUT( "N" );			return 1;		default:			EdbgOutputDebugString( "EP0/request = 0x%B\n", req.request );			break;	}	CLEAR_OPR_DE( UDCCS0 );	return 0;}static intEP0( void ){	if (UDCCS0 & SE) {		while (UDCCS0 & SE)			UDCCS0 = SSE;		state = 0;		DEBUG_OUT( "S" );		return 0;	}	if (UDCCS0 & SST) {		DEBUG_OUT( "T" );		while (UDCCS0 & SST)			UDCCS0 = SST;		return 0;	}	switch (state) {		case -1:			EdbgOutputDebugString( "UDC not initialized\n" );			break;		case 0:			if (UDCCS0 & OPR)				return EP0_State0();			else {				DEBUG_OUT( "x" );				return 0;			}		case 1:			EP0_SendData( 0, 0, NULL, 0 );			return 0;		default:			EdbgOutputDebugString( "Unknown state: %d\n", state );			break;	}	return 0;}static intUDCService( void ){	int ret = 0;	DWORD udcsr;	UDCSR;	udcsr = UDCSR;				/* read twice for correct value */	UDCSR = udcsr;				/* clears whole interrupts */	if (udcsr & RSTIR) {			/* reset */		/* TODO: see doc 11-66 */		while (UDCCR & SUSIM)			UDCCR &= ~SUSIM;		while (UDCIMP != MAX_PACKET_SIZE - 1)			UDCIMP = MAX_PACKET_SIZE - 1;	/* set in max packet size */		while (UDCOMP != MAX_PACKET_SIZE - 1)			UDCOMP = MAX_PACKET_SIZE - 1;	/* set out max packet size */		DEBUG_OUT( "!" );		state = 0;		return 0;	}	if (udcsr & EIR) {		ret |= EP0();		return ret;	}#if 0	if (udcsr & RIR) {		EdbgOutputDebugString( "EP1\n" );	}	if (udcsr & TIR) {		EdbgOutputDebugString( "EP2\n" );	}#endif /* 0 */	if (udcsr & RESIR) {		while (!(UDCCR & RESIM))			UDCCR |= RESIM;		while (UDCCR & RESIM)			UDCCR &= ~RESIM;		while (UDCCR & SUSIM)			UDCCR &= ~SUSIM;		DEBUG_OUT( "RESIR\n" );	}	if (udcsr & SUSIR) {		while (!(UDCCR & SUSIM))			UDCCR |= SUSIM;		DEBUG_OUT( "SUSIR\n" );	}	return ret;}intUSB_download( struct imginfo *img ){	DWORD Timeout;	int i;	struct fntable fn = {		USB_writechar,		USB_read	};	InitUDC();	EdbgOutputDebugString( "Ready to download image via USB\n" );	EdbgOutputDebugString( "* Please connect USB cable between PC and WID.\n" );	for (i = 4, Timeout = 0; i && !Timeout; i--) {		EdbgOutputDebugString( "%d\r", i );		Timeout = 0x200000;		while (Timeout) {			if (GPLR & GPIO_USP_MASK) {				if (UDCService())					break;			} else				Timeout--;		}	}	if (!Timeout) {		DeinitUDC();		return -2;	}	EdbgOutputDebugString( "\nUSB ready.\n" );	for (i = 0; i < 10; i++) {		EdbgOutputDebugString( "." );		Try {			download( &fn, img, 0 );		}		Catch_anonymous {			continue;		};		return 0;	}	EdbgOutputDebugString( "\nFail to synchonize with the host\n" );	return -2;}#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 == SA1110 */

⌨️ 快捷键说明

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