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

📄 usb_recv.c

📁 uboot针对三星公司的s3c2410(arm920T核)的初始化源代码。
💻 C
字号:
/* * 2004 (C) SAMSUNG ELECTRONICS  *       SW.LEE <hitchcar@samsung.com> *       ported to Uboot for S3C24A0A, S3C2440A * * usb_recv.c *  * S3C2410 USB receive function  * endpoint 1 * * bushi <bushi@mizi.com> */#include <common.h>#include <command.h>#include <s3c2440.h>#include <s3c24x0_usb.h>#include "usb_ctl.h"#include <asm/sizes.h>/* error number from linux */#define EINTR            4	/* Interrupted system call */#define EAGAIN          11	/* Try again */#define EBUSY           16	/* Device or resource busy */#define ENODEV          19	/* No such device *///#define USB_DEBUG 1#ifdef USB_DEBUG#define LOG(arg...) printf(__FILE__":"__FUNCTION__"(): " ##arg)#else#define LOG(arg...) (void)(0)#endifstatic unsigned char *ep1_buf;static unsigned int ep1_len;static usb_callback_t ep1_callback;static unsigned int ep1_curdmalen;static unsigned int ep1_remain;static unsigned int dmachn_rx;static unsigned int rx_pktsize;static unsigned int last_packet;extern unsigned int usbd_dn_cnt;extern unsigned int usbd_dn_addr;extern int DNW;int got_header = 0;union {	unsigned char data[9];	unsigned int val[2];} hdr;void ep1_dma_callback(void *buf_id, int size){	LOG("\n");}static void ep1_start(void){	LOG("\n");}static void ep1_done(int flag){	int size = ep1_len - ep1_remain;	LOG(" start\n");	if (!ep1_len)		return;	ep1_len = ep1_curdmalen = 0;#ifndef CONFIG_S3C2410_OYSTER	if (ep1_callback) {		ep1_callback(flag, size);	}#endif	LOG(" end\n");}void ep1_stall(void){	LOG(" start\n");	UD_INDEX = UD_INDEX_EP1;	UD_OCSR1 |= UD_OCSR1_SENDSTL;	/* send stall, force stall */	LOG(" end\n");}int ep1_init(int chn){	desc_t *pd = s3c24x0_usb_get_descriptor_ptr();	LOG(" start\n");	rx_pktsize = __le16_to_cpu(pd->b.ep1.wMaxPacketSize);	LOG("rx_pktsize = %d\n", rx_pktsize);	dmachn_rx = chn;	ep1_done(-EAGAIN);	LOG(" end\n");	return 0;}void ep1_reset(void){	desc_t *pd = s3c24x0_usb_get_descriptor_ptr();	rx_pktsize = __le16_to_cpu(pd->b.ep1.wMaxPacketSize);	LOG("rx_pktsize = %d\n", rx_pktsize);	UD_INDEX = UD_INDEX_EP1;	UD_OCSR1 &= ~(UD_OCSR1_SENDSTL);	ep1_done(-EINTR);}static void check_eof(int len){	int unit;	int index;	unsigned short cal = 0, rec;	unit = UD_MAXP * 8;//	/* DEBUGGING: SW.LEE//	if ( usbd_dn_cnt > 103500) printf("usbd_dn_cnt %d \n",usbd_dn_cnt);//	*/	if (DNW) {		if ( (hdr.val[1] == (usbd_dn_cnt + 8)) ){			rec=  *(unsigned short *)(usbd_dn_addr+usbd_dn_cnt-2);			printf("Recevie CRC: Received 0x%x \n",rec);			for (index = usbd_dn_addr + 8 ; index < hdr.val[1] ;index++)				cal +=  *((unsigned char *)(index));			printf("Calculated CRC: 0x%x bytes \n",cal);		}	}		if (0 == (usbd_dn_cnt % SZ_64K))		printf("*");	if (len != unit) {		printf("\nDownload done: Received %d(0x%x) bytes \n",		       usbd_dn_cnt, usbd_dn_cnt);		printf("Received data is located to 0x%08X \n",		       usbd_dn_addr);		got_header = 0;		usbd_dn_cnt = 0;	}}void ep1_int_hndlr(int udcsr){	//dma_addr_t dma_addr;	unsigned int len;	int status;	int recv_cnt;	if (DNW) {		UD_INDEX = UD_INDEX_EP3;	} else {		UD_INDEX = UD_INDEX_EP1;	}	status = UD_OCSR1;	LOG("0x%02x\n", UD_OCSR1);	LOG("0x%02x\n", UD_OCSR2);	LOG("0x%02x\n", UD_ICSR1);	LOG("0x%02x\n", UD_ICSR2);	if (status & UD_OCSR1_SENTSTL) {		if (DNW) {			UD_INDEX = UD_INDEX_EP3;		} else {			UD_INDEX = UD_INDEX_EP1;		}		UD_OCSR1 &= ~UD_OCSR1_SENTSTL;		LOG("UD_OCSR1_SENTSTL\n");		return;	}	if (status & UD_OCSR1_PKTRDY) {		LOG("ep1_len=%x\n", ep1_len);#if 0		if (!ep1_len) {			printf("usb_recv: RPC for non-existent buffer\n");			UD_INDEX = UD_INDEX_EP1;			UD_OCSR1 |= UD_OCSR1_FFLUSH;			//udelay(20);			UD_INDEX = UD_INDEX_EP1;			UD_OCSR1 &= ~UD_OCSR1_PKTRDY;			return;		}#endif		if (DNW) {			UD_INDEX = UD_INDEX_EP3;		} else {			UD_INDEX = UD_INDEX_EP1;		}			recv_cnt = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff;		if (DNW) {			if (!got_header) {				for (len = 0; len < 8; len++)					hdr.data[len] = (u_char) UD_FIFO3;				hdr.data[len] = '\0';				usbd_dn_addr = hdr.val[0];				last_packet = hdr.val[1]/64;				printf("\nDownload address:: 0x%X Size:: %ubytes\n", usbd_dn_addr, hdr.val[1] - 10);				//usbd_dn_cnt = 0;			}			for (len = 0;			     len < recv_cnt - 8 * (1 - got_header);			     len++) {				//ep1_buf[len] = (u_char) UD_FIFO3;				*(volatile unsigned char *) (usbd_dn_addr +							     usbd_dn_cnt) =				    (u_char) UD_FIFO3;				usbd_dn_cnt++;				LOG("ep1_buf[%d]=%x\n", len, ep1_buf[len]);			}			last_packet--;			got_header = 1;		} else {			LOG("recv_count = %d\n", recv_cnt);			for (len = 0; len < recv_cnt; len++) {				//ep1_buf[len] = (u_char) UD_FIFO1;				*(volatile unsigned char *) (usbd_dn_addr +							     usbd_dn_cnt) =				    (u_char) UD_FIFO1;				usbd_dn_cnt++;				LOG("ep1_buf[%d]=%x\n", len, ep1_buf[len]);			}			UD_INDEX = UD_INDEX_EP1;			UD_OCSR1 &= ~(0xFF); //shaju to clear			if(((UD_OCSR1&0x01) == 1) && ((UD_INT &0x8)==0) )			{						UD_INDEX = UD_INDEX_EP1;			recv_cnt = ((UD_OFCNTH << 8) | UD_OFCNTL) & 0xffff;				for (len = 0; len < recv_cnt; len++) {				//ep1_buf[len] = (u_char) UD_FIFO1;				*(volatile unsigned char *) (usbd_dn_addr +							     usbd_dn_cnt) =				    (u_char) UD_FIFO1;				usbd_dn_cnt++;				LOG("ep1_buf[%d]=%x\n", len, ep1_buf[len]);			}			UD_INDEX = UD_INDEX_EP1;		UD_OCSR1 &= ~(0xFF); //shaju to clear		}		check_eof(recv_cnt);					}		//      ep1_remain -= recv_cnt;		//      ep1_done(0);		if (DNW) {			UD_INDEX = UD_INDEX_EP3;		UD_OCSR1 &= ~(0xFF); //shaju to clear		}			     if(DNW){		/* H/w bug workaround */		if(!last_packet){                   if(hdr.val[1]%64){		      UD_INDEX = UD_INDEX_EP3;                      while(!(UD_OCSR1&0x1));                      len = ((UD_OFCNTH << 8) | UD_OFCNTL) &0xffff;                      if(len < hdr.val[1]%64)                        printf("File Download Should Be Aborted !!!\n");                   }                   for(len = hdr.val[1]%64; len; len--){        //We read only what we need                        *(volatile unsigned char *)(usbd_dn_addr +usbd_dn_cnt) = (u_char) UD_FIFO3;                        usbd_dn_cnt++;                   }                   UD_INDEX = UD_INDEX_EP3;                   UD_OCSR1 |= UD_OCSR1_FFLUSH;                   if(usbd_dn_cnt != (hdr.val[1] - 8)){                      printf("Size=%d usbd_dn_cnt=%d ", hdr.val[1], usbd_dn_cnt);                   }else{                      hdr.val[0] = 0;                      hdr.val[1] = 0;                      hdr.data[0] = *(volatile unsigned char *)(usbd_dn_addr + usbd_dn_cnt - 1);                      hdr.data[1] = *(volatile unsigned char *)(usbd_dn_addr + usbd_dn_cnt - 2);                      printf("Checksum of received file = 0x%X ", hdr.val[0]);                   }                   usbd_dn_cnt = got_header = 0;                }	     }	}}int s3c24x0_usb_recv(char *buf, int len, usb_callback_t callback){	LOG("\n");	if (ep1_len)		return -EBUSY;	//local_irq_save(flags);	ep1_buf = buf;	ep1_len = len;	ep1_callback = callback;	ep1_remain = len;	ep1_start();	// local_irq_restore(flags);	return 0;}void s3c24x0_usb_recv_reset(void){	LOG("\n");	ep1_reset();}void s3c24x0_usb_recv_stall(void){	LOG("\n");	ep1_stall();}

⌨️ 快捷键说明

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